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

1

2

3

4

5

6

7

8

9

10

11

12

26#include "llvm/ADT/ArrayRef.h"

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

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

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

30#include

31#include

32#include

33

34using namespace clang;

35

36DeducedTemplateStorage::DeducedTemplateStorage(TemplateName Underlying,

39 DefArgs.Args.size()),

40 Underlying(Underlying) {

42}

43

47}

48

54 ID.AddInteger(DefArgs.StartPos);

55 ID.AddInteger(DefArgs.Args.size());

58}

59

63}

64

67 return cast(

70}

71

74 return cast(

77}

78

81}

82

84 llvm::FoldingSetNodeID &ID, TemplateName Replacement, Decl *AssociatedDecl,

85 unsigned Index, std::optional PackIndex) {

86 Replacement.Profile(ID);

87 ID.AddPointer(AssociatedDecl);

88 ID.AddInteger(Index);

89 ID.AddInteger(PackIndex ? *PackIndex + 1 : 0);

90}

91

94 bool Final)

96 ArgPack.size()),

97 Arguments(ArgPack.data()), AssociatedDeclAndFinal(AssociatedDecl, Final) {

98 assert(AssociatedDecl != nullptr);

99}

100

105}

106

108 return AssociatedDeclAndFinal.getPointer();

109}

110

112 return AssociatedDeclAndFinal.getInt();

113}

114

116 llvm::FoldingSetNodeID &ID, ASTContext &Context,

118 bool Final) {

119 ArgPack.Profile(ID, Context);

120 ID.AddPointer(AssociatedDecl);

121 ID.AddInteger(Index);

122 ID.AddBoolean(Final);

123}

124

126 Storage = StorageType::getFromOpaqueValue(Ptr);

127}

128

131 : Storage(Storage) {}

133 : Storage(Storage) {}

135 : Storage(Storage) {}

137 : Storage(Storage) {}

142 : Storage(Deduced) {}

143

145

147 if (auto *ND = Storage.dyn_cast<Decl *>()) {

148 if (isa(ND))

150 assert(isa(ND));

152 }

153

154 if (isa<DependentTemplateName *>(Storage))

156 if (isa<QualifiedTemplateName *>(Storage))

158

160 cast<UncommonTemplateNameStorage *>(Storage);

169

172}

173

176 while (std::optional UnderlyingOrNone =

177 Name.desugar(IgnoreDeduced))

178 Name = *UnderlyingOrNone;

179

180 if (!IgnoreDeduced)

181 assert(Name.getAsDeducedTemplateName() == nullptr &&

182 "Unexpected canonical DeducedTemplateName; Did you mean to use "

183 "getTemplateDeclAndDefaultArgs instead?");

184

185 return cast_if_present(

186 dyn_cast_if_present<Decl *>(Name.Storage));

187}

188

189std::pair<TemplateDecl *, DefaultArguments>

191 for (TemplateName Name = *this; ; ) {

197 if (TD && DefArgs)

198 assert(DefArgs.StartPos + DefArgs.Args.size() <=

201 }

202 if (std::optional UnderlyingOrNone =

203 Name.desugar(false)) {

204 Name = *UnderlyingOrNone;

205 continue;

206 }

207 return {cast_if_present(Name.Storage.dyn_cast<Decl *>()), {}};

208 }

209}

210

212 if (Decl *D = dyn_cast_if_present<Decl *>(Storage)) {

213 if (auto *USD = dyn_cast(D))

215 return std::nullopt;

216 }

218 return QTN->getUnderlyingTemplate();

220 return S->getReplacement();

221 if (IgnoreDeduced)

223 return S->getUnderlying();

224 return std::nullopt;

225}

226

231

232 return nullptr;

233}

234

239

240 return nullptr;

241}

242

246 dyn_cast_if_present<UncommonTemplateNameStorage *>(Storage))

248

249 return nullptr;

250}

251

257

258 return nullptr;

259}

260

262 return dyn_cast_if_present<QualifiedTemplateName *>(Storage);

263}

264

267}

268

270 if (Decl *D = Storage.dyn_cast<Decl *>())

272 return USD;

274 return QTN->getUnderlyingTemplate().getAsUsingShadowDecl();

275 return nullptr;

276}

277

280 dyn_cast_if_present<UncommonTemplateNameStorage *>(Storage))

282

283 return nullptr;

284}

285

291 auto D = TemplateNameDependence::None;

292 if (auto *TTP = dyn_cast(Template)) {

293 D |= TemplateNameDependence::DependentInstantiation;

294 if (TTP->isParameterPack())

295 D |= TemplateNameDependence::UnexpandedPack;

296 }

297

298

299

300

301 if (Template->getDeclContext() &&

302 Template->getDeclContext()->isDependentContext())

303 D |= TemplateNameDependence::DependentInstantiation;

304 return D;

305 }

308 TemplateNameDependence D = S->getUnderlyingTemplate().getDependence();

311 return D;

312 }

315 auto D = TemplateNameDependence::DependentInstantiation;

317 return D;

318 }

321 return S->getReplacement().getDependence();

322 }

324 return TemplateNameDependence::UnexpandedPack |

325 TemplateNameDependence::DependentInstantiation;

331 return D;

332 }

334 return TemplateNameDependence::DependentInstantiation;

336 llvm_unreachable("overloaded templates shouldn't survive to here.");

337 }

338 llvm_unreachable("Unknown TemplateName kind");

339}

340

342 return getDependence() & TemplateNameDependence::Dependent;

343}

344

346 return getDependence() & TemplateNameDependence::Instantiation;

347}

348

350 return getDependence() & TemplateNameDependence::UnexpandedPack;

351}

352

355 auto handleAnonymousTTP = [](TemplateDecl *TD, raw_ostream &OS) {

358 OS << "template-parameter-" << TTP->getDepth() << "-" << TTP->getIndex();

359 return true;

360 }

361 return false;

362 };

365

366

367

368

369

370

371

372

373

375 if (handleAnonymousTTP(Template, OS))

376 return;

379 else

380 Template->printQualifiedName(OS, Policy);

384 NNS->print(OS, Policy);

385 if (QTN->hasTemplateKeyword())

386 OS << "template ";

387

388 TemplateName Underlying = QTN->getUnderlyingTemplate();

391

393

394 if (handleAnonymousTTP(UTD, OS))

395 return;

396

399 isa(UTD))

400 OS << II->deuglifiedName();

401 else

402 OS << *UTD;

405 NNS->print(OS, Policy);

406 OS << "template ";

407

408 if (DTN->isIdentifier())

409 OS << DTN->getIdentifier()->getName();

410 else

414 subst->getReplacement().print(OS, Policy, Qual);

417 OS << *SubstPack->getParameterPack();

419 Assumed->getDeclName().print(OS, Policy);

421 Deduced->getUnderlying().print(OS, Policy);

423 OS << ":" << DefArgs.StartPos;

425 } else {

428 (*OTS->begin())->printName(OS, Policy);

429 }

430}

431

434 std::string NameStr;

435 llvm::raw_string_ostream OS(NameStr);

437 LO.CPlusPlus = true;

438 LO.Bool = true;

439 OS << '\'';

441 OS << '\'';

442 return DB << NameStr;

443}

Defines the Diagnostic-related interfaces.

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the C++ template declaration subclasses.

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

Defines the clang::LangOptions interface.

Defines an enumeration for C++ overloaded operators.

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

A structure for storing the information associated with a name that has been assumed to be a template...

Decl - This represents one declaration (or definition), e.g.

void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const

TemplateName getUnderlying() const

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

DefaultArguments getDefaultArguments() const

Represents a dependent template name that cannot be resolved prior to template instantiation.

One of these records is kept for each identifier that is lexed.

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

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

Represents a C++ nested name specifier, such as "\::std::vector::".

A structure for storing the information associated with an overloaded template name.

Represents a template name as written in source code.

The streaming interface shared between DiagnosticBuilder and PartialDiagnostic.

A structure for storing an already-substituted template template parameter pack.

Decl * getAssociatedDecl() const

A template-like entity which owns the whole pattern being substituted.

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

TemplateTemplateParmDecl * getParameterPack() const

Retrieve the template template parameter pack being substituted.

TemplateArgument getArgumentPack() const

Retrieve the template template argument pack with which this parameter was substituted.

unsigned getIndex() const

Returns the index of the replaced parameter in the associated declaration.

SubstTemplateTemplateParmPackStorage(ArrayRef< TemplateArgument > ArgPack, Decl *AssociatedDecl, unsigned Index, bool Final)

A structure for storing the information associated with a substituted template template parameter.

std::optional< unsigned > getPackIndex() const

void Profile(llvm::FoldingSetNodeID &ID)

TemplateTemplateParmDecl * getParameter() const

unsigned getIndex() const

Returns the index of the replaced parameter in the associated declaration.

Decl * getAssociatedDecl() const

A template-like entity which owns the whole pattern being substituted.

Represents a template argument.

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

Used to insert TemplateArguments into FoldingSets.

The base class of all kinds of template declarations (e.g., class, function, etc.).

TemplateParameterList * getTemplateParameters() const

Get the list of template parameters.

Represents a C++ template name within the type system.

TemplateNameDependence getDependence() const

TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const

Retrieve the underlying template declaration that this template name refers to, if known.

DeducedTemplateStorage * getAsDeducedTemplateName() const

Retrieve the deduced template info, if any.

bool isNull() const

Determine whether this template name is NULL.

DependentTemplateName * getAsDependentTemplateName() const

Retrieve the underlying dependent template name structure, if any.

QualifiedTemplateName * getAsQualifiedTemplateName() const

Retrieve the underlying qualified template name structure, if any.

std::optional< TemplateName > desugar(bool IgnoreDeduced) const

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

Print the template name.

OverloadedTemplateStorage * getAsOverloadedTemplate() const

Retrieve the underlying, overloaded function template declarations that this template name refers to,...

bool containsUnexpandedParameterPack() const

Determines whether this template name contains an unexpanded parameter pack (for C++0x variadic templ...

AssumedTemplateStorage * getAsAssumedTemplateName() const

Retrieve information on a name that has been assumed to be a template-name in order to permit a call ...

@ UsingTemplate

A template name that refers to a template declaration found through a specific using shadow declarati...

@ OverloadedTemplate

A set of overloaded template declarations.

@ Template

A single template declaration.

@ DependentTemplate

A dependent template name that has not been resolved to a template (or set of templates).

@ SubstTemplateTemplateParm

A template template parameter that has been substituted for some other template name.

@ SubstTemplateTemplateParmPack

A template template parameter pack that has been substituted for a template template argument pack,...

@ DeducedTemplate

A template name that refers to another TemplateName with deduced default arguments.

@ QualifiedTemplate

A qualified template name, where the qualification is kept to describe the source code as written.

@ AssumedTemplate

An unqualified-id that has been assumed to name a function template that will be found by ADL.

UsingShadowDecl * getAsUsingShadowDecl() const

Retrieve the using shadow declaration through which the underlying template declaration is introduced...

SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack() const

Retrieve the substituted template template parameter pack, if known.

void Profile(llvm::FoldingSetNodeID &ID)

bool isDependent() const

Determines whether this is a dependent template name.

std::pair< TemplateDecl *, DefaultArguments > getTemplateDeclAndDefaultArgs() const

Retrieves the underlying template declaration that this template name refers to, along with the deduc...

SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm() const

Retrieve the substituted template template parameter, if known.

bool isInstantiationDependent() const

Determines whether this is a template name that somehow depends on a template parameter.

TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.

Implementation class used to describe either a set of overloaded template names or an already-substit...

SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack()

SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm()

AssumedTemplateStorage * getAsAssumedTemplateName()

DeducedTemplateStorage * getAsDeducedTemplateName()

OverloadedTemplateStorage * getAsOverloadedStorage()

Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...

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

TemplateNameDependence toTemplateNameDependence(NestedNameSpecifierDependence D)

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

Insertion operator for diagnostics.

TemplateParameterList * getReplacedTemplateParameterList(Decl *D)

Internal helper used by Subst* nodes to retrieve the parameter list for their AssociatedDecl.

void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)

Print a template argument list, including the '<' and '>' enclosing the template arguments.

const char * getOperatorSpelling(OverloadedOperatorKind Operator)

Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.

ArrayRef< TemplateArgument > Args

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

unsigned CleanUglifiedParameters

Whether to strip underscores when printing reserved parameter names.

unsigned Data

The pack index, or the number of stored templates or template arguments, depending on which subclass ...