clang: lib/AST/TemplateBase.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

30#include "llvm/ADT/APSInt.h"

31#include "llvm/ADT/FoldingSet.h"

32#include "llvm/ADT/StringExtras.h"

33#include "llvm/Support/Compiler.h"

34#include "llvm/Support/ErrorHandling.h"

35#include "llvm/Support/raw_ostream.h"

36#include

37#include

38#include

39#include

40#include

41

42using namespace clang;

43

44

45

46

47

48

49

50

51

52

53

57 const llvm::APSInt &Val = TemplArg.getAsIntegral();

58

61 for (const EnumConstantDecl *ECD : ET->getDecl()->enumerators()) {

62

63

64

65

66 if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {

67 ECD->printQualifiedName(Out, Policy);

68 return;

69 }

70 }

71 }

72 }

73

75 IncludeType = false;

76

79 Out << (Val.getBoolValue() ? "true" : "false");

80 else

81 Out << Val;

83 if (IncludeType) {

85 Out << "(signed char)";

87 Out << "(unsigned char)";

88 }

90 Out);

94 Kind = CharacterLiteralKind::Wide;

96 Kind = CharacterLiteralKind::UTF8;

98 Kind = CharacterLiteralKind::UTF16;

100 Kind = CharacterLiteralKind::UTF32;

101 else

102 Kind = CharacterLiteralKind::Ascii;

104 } else if (IncludeType) {

106 switch (BT->getKind()) {

107 case BuiltinType::ULongLong:

108 Out << Val << "ULL";

109 break;

110 case BuiltinType::LongLong:

111 Out << Val << "LL";

112 break;

113 case BuiltinType::ULong:

114 Out << Val << "UL";

115 break;

116 case BuiltinType::Long:

117 Out << Val << "L";

118 break;

119 case BuiltinType::UInt:

120 Out << Val << "U";

121 break;

122 case BuiltinType::Int:

123 Out << Val;

124 break;

125 default:

127 << Val;

128 break;

129 }

130 } else

132 << Val;

133 } else

134 Out << Val;

135}

136

138 unsigned count = 0;

139 while (const auto *arrayType = type->getAsArrayTypeUnsafe()) {

140 count++;

142 }

143 return count;

144}

145

147

148

149

154 return true;

155}

156

157

158

159

160

161void TemplateArgument::initFromType(QualType T, bool IsNullPtr,

162 bool IsDefaulted) {

166}

167

169 bool IsDefaulted) {

170 assert(D && "Expected decl");

172 DeclArg.IsDefaulted = IsDefaulted;

175}

176

177void TemplateArgument::initFromIntegral(const ASTContext &Ctx,

178 const llvm::APSInt &Value,

181 Integer.IsDefaulted = IsDefaulted;

182

185

186 unsigned NumWords = Value.getNumWords();

187 if (NumWords > 1) {

188 void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));

189 std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));

191 } else {

193 }

194

196}

197

199 const APValue &V, bool IsDefaulted) {

201 Value.IsDefaulted = IsDefaulted;

204 Value.Type = Type.getAsOpaquePtr();

205}

206

209 bool IsDefaulted) {

210 initFromIntegral(Ctx, Value, Type, IsDefaulted);

211}

212

215

216 if (V.isMemberPointer() && V.getMemberPointerPath().empty())

217 return V.getMemberPointerDecl();

218

219

220

221 if (V.isStruct() || V.isUnion()) {

222

223

225 return nullptr;

227 }

228

229

230

231 if (V.isLValue() && V.hasLValuePath() && V.getLValuePath().empty() &&

232 V.isLValueOnePastTheEnd())

233 return V.getLValueBase().dyn_cast<const ValueDecl *>();

234

235

236 return nullptr;

237}

238

240 const APValue &V, bool IsDefaulted) {

242 initFromIntegral(Ctx, V.getInt(), Type, IsDefaulted);

243 else if ((V.isLValue() && V.isNullPointer()) ||

244 (V.isMemberPointer() && V.getMemberPointerDecl()))

245 initFromType(Type, true, IsDefaulted);

247

248 initFromDeclaration(const_cast<ValueDecl *>(VD), Type, IsDefaulted);

249 else

250 initFromStructural(Ctx, Type, V, IsDefaulted);

251}

252

256 if (Args.empty())

258

260}

261

263 auto Deps = TemplateArgumentDependence::None;

266 llvm_unreachable("Should not have a NULL template argument");

267

270 if (isa(getAsType()))

271 Deps |= TemplateArgumentDependence::Dependent;

272 return Deps;

273

276

278 return TemplateArgumentDependence::Dependent |

279 TemplateArgumentDependence::Instantiation;

280

282 auto *DC = dyn_cast(getAsDecl());

283 if (!DC)

285 if (DC->isDependentContext())

286 Deps = TemplateArgumentDependence::Dependent |

287 TemplateArgumentDependence::Instantiation;

288 return Deps;

289 }

290

294 return TemplateArgumentDependence::None;

295

298 if (isa(getAsExpr()))

299 Deps |= TemplateArgumentDependence::Dependent |

300 TemplateArgumentDependence::Instantiation;

301 return Deps;

302

305 Deps |= P.getDependence();

306 return Deps;

307 }

308 llvm_unreachable("unhandled ArgKind");

309}

310

312 return getDependence() & TemplateArgumentDependence::Dependent;

313}

314

316 return getDependence() & TemplateArgumentDependence::Instantiation;

317}

318

328 return false;

329

331 return true;

332

334 return isa(getAsType());

335

337 return isa(getAsExpr());

338 }

339

340 llvm_unreachable("Invalid TemplateArgument Kind!");

341}

342

344 return getDependence() & TemplateArgumentDependence::UnexpandedPack;

345}

346

351

352 return std::nullopt;

353}

354

363

366

369

372

375

378 }

379

380 llvm_unreachable("Invalid TemplateArgument Kind!");

381}

382

385 ID.AddInteger(getKind());

388 break;

389

392 break;

393

396 break;

397

401 break;

402

404 ID.AddInteger(TemplateArg.NumExpansions);

405 [[fallthrough]];

408 break;

409

413 break;

414

418 break;

419

422 break;

423

425 ID.AddInteger(Args.NumArgs);

426 for (unsigned I = 0; I != Args.NumArgs; ++I)

427 Args.Args[I].Profile(ID, Context);

428 }

429}

430

432 if (getKind() != Other.getKind()) return false;

433

440

444 TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;

445

449

453

456 Other.getStructuralValueType().getCanonicalType())

457 return false;

458

459 llvm::FoldingSetNodeID A, B;

461 Other.getAsStructuralValue().Profile(B);

462 return A == B;

463 }

464

466 if (Args.NumArgs != Other.Args.NumArgs) return false;

467 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)

468 if (Args.Args[I].structurallyEquals(Other.Args.Args[I]))

469 return false;

470 return true;

471 }

472

473 llvm_unreachable("Invalid TemplateArgument Kind!");

474}

475

478

482

484 return cast(getAsExpr())->getPattern();

485

488

497 }

498

499 llvm_unreachable("Invalid TemplateArgument Kind!");

500}

501

503 bool IncludeType) const {

504

507 Out << "(no value)";

508 break;

509

514 break;

515 }

516

520 if (auto *TPO = dyn_cast(ND)) {

521 TPO->getType().getUnqualifiedType().print(Out, Policy);

522 TPO->printAsInit(Out, Policy);

523 break;

524 }

525 }

526 if (auto *VD = dyn_cast(ND)) {

528 Out << "&";

529 }

531 break;

532 }

533

536 break;

537

539

540 Out << "nullptr";

541 break;

542

545 break;

546 }

547

550 Out << "...";

551 break;

552

555 break;

556

559 break;

560

562 Out << "<";

563 bool First = true;

567 else

568 Out << ", ";

569

570 P.print(Policy, Out, IncludeType);

571 }

572 Out << ">";

573 break;

574 }

575}

576

577

578

579

580

582 switch (Argument.getKind()) {

585

588

591

594 return TSI->getTypeLoc().getSourceRange();

595 else

597

603

609

612

615

619 }

620

621 llvm_unreachable("Invalid TemplateArgument Kind!");

622}

623

624template

628

629

630 return DB << "(null template argument)";

631

634

637

639 return DB << "nullptr";

640

643

645

647 llvm::raw_svector_ostream OS(Str);

649 LangOpts.CPlusPlus = true;

653 return DB << OS.str();

654 }

655

658

661

663

664

665

667 llvm::raw_svector_ostream OS(Str);

669 LangOpts.CPlusPlus = true;

672 return DB << OS.str();

673 }

674

676

678 llvm::raw_svector_ostream OS(Str);

680 LangOpts.CPlusPlus = true;

682 Arg.print(Policy, OS, true);

683 return DB << OS.str();

684 }

685 }

686

687 llvm_unreachable("Invalid TemplateArgument Kind!");

688}

689

693}

694

698 TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo;

700 Template->QualifierLocData = QualifierLoc.getOpaqueData();

701 Template->TemplateNameLoc = TemplateNameLoc;

702 Template->EllipsisLoc = EllipsisLoc;

704}

705

709 std::size_t size = totalSizeToAlloc(List.size());

712}

713

717 if (!List)

718 return nullptr;

719 std::size_t size =

720 totalSizeToAlloc(List->getNumTemplateArgs());

723}

724

725ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(

730

731 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();

734}

735

736ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(

741

742 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();

745}

746

754

757}

758

765}

766

774

776 Deps |= Info[i].getArgument().getDependence();

777

779 }

780}

781

788}

Defines the clang::ASTContext interface.

Defines the Diagnostic-related interfaces.

Defines the C++ template declaration subclasses.

Defines the clang::Expr interface and subclasses for C++ expressions.

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

Defines the clang::LangOptions interface.

static std::string toString(const clang::SanitizerSet &Sanitizers)

Produce a string containing comma-separated names of sanitizers in Sanitizers set.

static bool isRecordType(QualType T)

Defines the clang::SourceLocation class and associated facilities.

static const ValueDecl * getAsSimpleValueDeclRef(const ASTContext &Ctx, QualType T, const APValue &V)

static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out, const PrintingPolicy &Policy, bool IncludeType)

Print a template integral argument value.

static unsigned getArrayDepth(QualType type)

static const T & DiagTemplateArg(const T &DB, const TemplateArgument &Arg)

static bool needsAmpersandOnTemplateArg(QualType paramType, QualType argType)

Defines the clang::TypeLoc interface and its subclasses.

C Language Family Type Representation.

APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...

void Profile(llvm::FoldingSetNodeID &ID) const

profile this value.

void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

TemplateParamObjectDecl * getTemplateParamObjectDecl(QualType T, const APValue &V) const

Return the template parameter object of the given type with the given value.

void * Allocate(size_t Size, unsigned Align=8) const

void addDestruction(T *Ptr) const

If T isn't trivially destructible, calls AddDeallocation to register it for destruction.

This class is used for builtin types like 'int'.

static void print(unsigned val, CharacterLiteralKind Kind, raw_ostream &OS)

DeclContext * getDeclContext()

An instance of this object exists for each enum constant that is defined.

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

This represents a decl that may have a name.

void printQualifiedName(raw_ostream &OS) const

Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...

A C++ nested-name-specifier augmented with source location information.

void * getOpaqueData() const

Retrieve the opaque pointer that refers to source-location data.

NestedNameSpecifier * getNestedNameSpecifier() const

Retrieve the nested-name-specifier to which this instance refers.

Represents a pack expansion of types.

A (possibly-)qualified type.

void Profile(llvm::FoldingSetNodeID &ID) const

const Type * getTypePtr() const

Retrieves a pointer to the underlying (unqualified) type.

void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const

void * getAsOpaquePtr() const

static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

A trivial tuple used to represent a source range.

void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const

Produce a unique representation of the given statement.

The streaming interface shared between DiagnosticBuilder and PartialDiagnostic.

A convenient class for passing around template argument information.

SourceLocation getRAngleLoc() const

void setLAngleLoc(SourceLocation Loc)

void setRAngleLoc(SourceLocation Loc)

void addArgument(const TemplateArgumentLoc &Loc)

SourceLocation getLAngleLoc() const

Location wrapper for a TemplateArgument.

SourceLocation getTemplateEllipsisLoc() const

Expr * getSourceStructuralValueExpression() const

Expr * getSourceIntegralExpression() const

SourceLocation getTemplateNameLoc() const

TypeSourceInfo * getTypeSourceInfo() const

Expr * getSourceNullPtrExpression() const

SourceRange getSourceRange() const LLVM_READONLY

NestedNameSpecifierLoc getTemplateQualifierLoc() const

Expr * getSourceDeclExpression() const

Expr * getSourceExpression() const

Represents a template argument.

QualType getStructuralValueType() const

Get the type of a StructuralValue.

QualType getParamTypeForDecl() const

Expr * getAsExpr() const

Retrieve the template argument as an expression.

bool isDependent() const

Whether this template argument is dependent on a template parameter such that its result can change f...

std::optional< unsigned > getNumTemplateExpansions() const

Retrieve the number of expansions that a template template argument expansion will produce,...

bool isInstantiationDependent() const

Whether this template argument is dependent on a template parameter.

constexpr TemplateArgument()

Construct an empty, invalid template argument.

QualType getNonTypeTemplateArgumentType() const

If this is a non-type template argument, get its type.

void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const

Used to insert TemplateArguments into FoldingSets.

QualType getAsType() const

Retrieve the type for a type template argument.

llvm::APSInt getAsIntegral() const

Retrieve the template argument as an integral value.

QualType getNullPtrType() const

Retrieve the type for null non-type template argument.

static TemplateArgument CreatePackCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)

Create a new template argument pack by copying the given set of template arguments.

TemplateName getAsTemplate() const

Retrieve the template name for a template name argument.

bool containsUnexpandedParameterPack() const

Whether this template argument contains an unexpanded parameter pack.

TemplateArgument getPackExpansionPattern() const

When the template argument is a pack expansion, returns the pattern of the pack expansion.

static TemplateArgument getEmptyPack()

bool structurallyEquals(const TemplateArgument &Other) const

Determines whether two template arguments are superficially the same.

void print(const PrintingPolicy &Policy, raw_ostream &Out, bool IncludeType) const

Print this template argument to the given output stream.

QualType getIntegralType() const

Retrieve the type of the integral value.

ValueDecl * getAsDecl() const

Retrieve the declaration for a declaration non-type template argument.

ArrayRef< TemplateArgument > pack_elements() const

Iterator range referencing all of the elements of a template argument pack.

@ Declaration

The template argument is a declaration that was provided for a pointer, reference,...

@ Template

The template argument is a template name that was provided for a template template parameter.

@ StructuralValue

The template argument is a non-type template argument that can't be represented by the special-case D...

@ Pack

The template argument is actually a parameter pack.

@ TemplateExpansion

The template argument is a pack expansion of a template name that was provided for a template templat...

@ NullPtr

The template argument is a null pointer or null pointer to member that was provided for a non-type te...

@ Type

The template argument is a type.

@ Null

Represents an empty template argument, e.g., one that has not been deduced.

@ Integral

The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...

@ Expression

The template argument is an expression, and we've not resolved it to one of the other forms yet,...

ArgKind getKind() const

Return the kind of stored template argument.

TemplateArgumentDependence getDependence() const

bool isPackExpansion() const

Determine whether this template argument is a pack expansion.

TemplateName getAsTemplateOrTemplatePattern() const

Retrieve the template argument as a template name; if the argument is a pack expansion,...

const APValue & getAsStructuralValue() const

Get the value of a StructuralValue.

void print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const

Print the template name.

A container of type source information.

The base class of the type hierarchy.

bool isBooleanType() const

bool isPointerType() const

const T * castAs() const

Member-template castAs.

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

bool isIntegralOrEnumerationType() const

Determine whether this type is an integral or enumeration type.

bool isAnyCharacterType() const

Determine whether this type is any of the built-in character types.

bool isInstantiationDependentType() const

Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...

bool isSpecificBuiltinType(unsigned K) const

Test for a particular builtin type.

bool isDependentType() const

Whether this type is a dependent type, meaning that its definition somehow depends on a template para...

bool isChar16Type() const

QualType getCanonicalTypeInternal() const

bool isMemberPointerType() const

bool isChar32Type() const

bool isWideCharType() const

const T * getAs() const

Member-template getAs'.

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const AstTypeMatcher< ArrayType > arrayType

Matches all kinds of arrays.

The JSON file list parser is used to communicate input to InstallAPI.

const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)

Insertion operator for diagnostics.

const FunctionProtoType * T

TemplateArgumentDependence toTemplateArgumentDependence(TypeDependence D)

@ Other

Other implicit parameter.

__UINTPTR_TYPE__ uintptr_t

An unsigned integer type with the property that any valid pointer to void can be converted to this ty...

Represents an explicit template argument list in C++, e.g., the "" in "sort".

SourceLocation RAngleLoc

The source location of the right angle bracket ('>').

SourceLocation LAngleLoc

The source location of the left angle bracket ('<').

SourceLocation getLAngleLoc() const

static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)

unsigned getNumTemplateArgs() const

unsigned NumTemplateArgs

The number of template arguments in TemplateArgs.

SourceLocation getRAngleLoc() const

SourceLocation LAngleLoc

The source location of the left angle bracket ('<').

void copyInto(const TemplateArgumentLoc *ArgArray, TemplateArgumentListInfo &List) const

unsigned NumTemplateArgs

The number of template arguments in TemplateArgs.

void initializeFrom(SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &List, TemplateArgumentLoc *OutArgArray)

SourceLocation RAngleLoc

The source location of the right angle bracket ('>').

SourceLocation TemplateKWLoc

The source location of the template keyword; this is used as part of the representation of qualified ...

Describes how types, statements, expressions, and declarations should be printed.

unsigned MSVCFormatting

Use whitespace and punctuation like MSVC does.

unsigned SuppressStrongLifetime

When true, suppress printing of the __strong lifetime qualifier in ARC.

unsigned UseEnumerators

Whether to print enumerator non-type template parameters with a matching enumerator name or via cast ...

TemplateArgumentLocInfo()