TemplateBase.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. //===--- TemplateBase.cpp - Common template AST class implementation ------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements common classes used throughout C++ template
  11. // representations.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "clang/AST/TemplateBase.h"
  15. #include "clang/AST/ASTContext.h"
  16. #include "clang/AST/DeclBase.h"
  17. #include "clang/AST/DeclTemplate.h"
  18. #include "clang/AST/Expr.h"
  19. #include "clang/AST/ExprCXX.h"
  20. #include "clang/AST/Type.h"
  21. #include "clang/AST/TypeLoc.h"
  22. #include "clang/Basic/Diagnostic.h"
  23. #include "llvm/ADT/FoldingSet.h"
  24. #include "llvm/ADT/SmallString.h"
  25. #include "llvm/Support/raw_ostream.h"
  26. #include <algorithm>
  27. using namespace clang;
  28. /// \brief Print a template integral argument value.
  29. ///
  30. /// \param TemplArg the TemplateArgument instance to print.
  31. ///
  32. /// \param Out the raw_ostream instance to use for printing.
  33. ///
  34. /// \param Policy the printing policy for EnumConstantDecl printing.
  35. static void printIntegral(const TemplateArgument &TemplArg,
  36. raw_ostream &Out, const PrintingPolicy& Policy) {
  37. const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
  38. const llvm::APSInt &Val = TemplArg.getAsIntegral();
  39. if (const EnumType *ET = T->getAs<EnumType>()) {
  40. for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) {
  41. // In Sema::CheckTemplateArugment, enum template arguments value are
  42. // extended to the size of the integer underlying the enum type. This
  43. // may create a size difference between the enum value and template
  44. // argument value, requiring isSameValue here instead of operator==.
  45. if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
  46. ECD->printQualifiedName(Out, Policy);
  47. return;
  48. }
  49. }
  50. }
  51. if (T->isBooleanType()) {
  52. Out << (Val.getBoolValue() ? "true" : "false");
  53. } else if (T->isCharType()) {
  54. const char Ch = Val.getZExtValue();
  55. Out << ((Ch == '\'') ? "'\\" : "'");
  56. Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
  57. Out << "'";
  58. } else {
  59. Out << Val;
  60. }
  61. }
  62. //===----------------------------------------------------------------------===//
  63. // TemplateArgument Implementation
  64. //===----------------------------------------------------------------------===//
  65. TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
  66. QualType Type) {
  67. Integer.Kind = Integral;
  68. // Copy the APSInt value into our decomposed form.
  69. Integer.BitWidth = Value.getBitWidth();
  70. Integer.IsUnsigned = Value.isUnsigned();
  71. // If the value is large, we have to get additional memory from the ASTContext
  72. unsigned NumWords = Value.getNumWords();
  73. if (NumWords > 1) {
  74. void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
  75. std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
  76. Integer.pVal = static_cast<uint64_t *>(Mem);
  77. } else {
  78. Integer.VAL = Value.getZExtValue();
  79. }
  80. Integer.Type = Type.getAsOpaquePtr();
  81. }
  82. TemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context,
  83. const TemplateArgument *Args,
  84. unsigned NumArgs) {
  85. if (NumArgs == 0)
  86. return getEmptyPack();
  87. TemplateArgument *Storage = new (Context) TemplateArgument [NumArgs];
  88. std::copy(Args, Args + NumArgs, Storage);
  89. return TemplateArgument(Storage, NumArgs);
  90. }
  91. bool TemplateArgument::isDependent() const {
  92. switch (getKind()) {
  93. case Null:
  94. llvm_unreachable("Should not have a NULL template argument");
  95. case Type:
  96. return getAsType()->isDependentType() ||
  97. isa<PackExpansionType>(getAsType());
  98. case Template:
  99. return getAsTemplate().isDependent();
  100. case TemplateExpansion:
  101. return true;
  102. case Declaration:
  103. if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
  104. return DC->isDependentContext();
  105. return getAsDecl()->getDeclContext()->isDependentContext();
  106. case NullPtr:
  107. return false;
  108. case Integral:
  109. // Never dependent
  110. return false;
  111. case Expression:
  112. return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent() ||
  113. isa<PackExpansionExpr>(getAsExpr()));
  114. case Pack:
  115. for (const auto &P : pack_elements())
  116. if (P.isDependent())
  117. return true;
  118. return false;
  119. }
  120. llvm_unreachable("Invalid TemplateArgument Kind!");
  121. }
  122. bool TemplateArgument::isInstantiationDependent() const {
  123. switch (getKind()) {
  124. case Null:
  125. llvm_unreachable("Should not have a NULL template argument");
  126. case Type:
  127. return getAsType()->isInstantiationDependentType();
  128. case Template:
  129. return getAsTemplate().isInstantiationDependent();
  130. case TemplateExpansion:
  131. return true;
  132. case Declaration:
  133. if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
  134. return DC->isDependentContext();
  135. return getAsDecl()->getDeclContext()->isDependentContext();
  136. case NullPtr:
  137. return false;
  138. case Integral:
  139. // Never dependent
  140. return false;
  141. case Expression:
  142. return getAsExpr()->isInstantiationDependent();
  143. case Pack:
  144. for (const auto &P : pack_elements())
  145. if (P.isInstantiationDependent())
  146. return true;
  147. return false;
  148. }
  149. llvm_unreachable("Invalid TemplateArgument Kind!");
  150. }
  151. bool TemplateArgument::isPackExpansion() const {
  152. switch (getKind()) {
  153. case Null:
  154. case Declaration:
  155. case Integral:
  156. case Pack:
  157. case Template:
  158. case NullPtr:
  159. return false;
  160. case TemplateExpansion:
  161. return true;
  162. case Type:
  163. return isa<PackExpansionType>(getAsType());
  164. case Expression:
  165. return isa<PackExpansionExpr>(getAsExpr());
  166. }
  167. llvm_unreachable("Invalid TemplateArgument Kind!");
  168. }
  169. bool TemplateArgument::containsUnexpandedParameterPack() const {
  170. switch (getKind()) {
  171. case Null:
  172. case Declaration:
  173. case Integral:
  174. case TemplateExpansion:
  175. case NullPtr:
  176. break;
  177. case Type:
  178. if (getAsType()->containsUnexpandedParameterPack())
  179. return true;
  180. break;
  181. case Template:
  182. if (getAsTemplate().containsUnexpandedParameterPack())
  183. return true;
  184. break;
  185. case Expression:
  186. if (getAsExpr()->containsUnexpandedParameterPack())
  187. return true;
  188. break;
  189. case Pack:
  190. for (const auto &P : pack_elements())
  191. if (P.containsUnexpandedParameterPack())
  192. return true;
  193. break;
  194. }
  195. return false;
  196. }
  197. Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
  198. assert(getKind() == TemplateExpansion);
  199. if (TemplateArg.NumExpansions)
  200. return TemplateArg.NumExpansions - 1;
  201. return None;
  202. }
  203. void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
  204. const ASTContext &Context) const {
  205. ID.AddInteger(getKind());
  206. switch (getKind()) {
  207. case Null:
  208. break;
  209. case Type:
  210. getAsType().Profile(ID);
  211. break;
  212. case NullPtr:
  213. getNullPtrType().Profile(ID);
  214. break;
  215. case Declaration:
  216. ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : nullptr);
  217. break;
  218. case Template:
  219. case TemplateExpansion: {
  220. TemplateName Template = getAsTemplateOrTemplatePattern();
  221. if (TemplateTemplateParmDecl *TTP
  222. = dyn_cast_or_null<TemplateTemplateParmDecl>(
  223. Template.getAsTemplateDecl())) {
  224. ID.AddBoolean(true);
  225. ID.AddInteger(TTP->getDepth());
  226. ID.AddInteger(TTP->getPosition());
  227. ID.AddBoolean(TTP->isParameterPack());
  228. } else {
  229. ID.AddBoolean(false);
  230. ID.AddPointer(Context.getCanonicalTemplateName(Template)
  231. .getAsVoidPointer());
  232. }
  233. break;
  234. }
  235. case Integral:
  236. getAsIntegral().Profile(ID);
  237. getIntegralType().Profile(ID);
  238. break;
  239. case Expression:
  240. getAsExpr()->Profile(ID, Context, true);
  241. break;
  242. case Pack:
  243. ID.AddInteger(Args.NumArgs);
  244. for (unsigned I = 0; I != Args.NumArgs; ++I)
  245. Args.Args[I].Profile(ID, Context);
  246. }
  247. }
  248. bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
  249. if (getKind() != Other.getKind()) return false;
  250. switch (getKind()) {
  251. case Null:
  252. case Type:
  253. case Expression:
  254. case Template:
  255. case TemplateExpansion:
  256. case NullPtr:
  257. return TypeOrValue.V == Other.TypeOrValue.V;
  258. case Declaration:
  259. return getAsDecl() == Other.getAsDecl();
  260. case Integral:
  261. return getIntegralType() == Other.getIntegralType() &&
  262. getAsIntegral() == Other.getAsIntegral();
  263. case Pack:
  264. if (Args.NumArgs != Other.Args.NumArgs) return false;
  265. for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
  266. if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
  267. return false;
  268. return true;
  269. }
  270. llvm_unreachable("Invalid TemplateArgument Kind!");
  271. }
  272. TemplateArgument TemplateArgument::getPackExpansionPattern() const {
  273. assert(isPackExpansion());
  274. switch (getKind()) {
  275. case Type:
  276. return getAsType()->getAs<PackExpansionType>()->getPattern();
  277. case Expression:
  278. return cast<PackExpansionExpr>(getAsExpr())->getPattern();
  279. case TemplateExpansion:
  280. return TemplateArgument(getAsTemplateOrTemplatePattern());
  281. case Declaration:
  282. case Integral:
  283. case Pack:
  284. case Null:
  285. case Template:
  286. case NullPtr:
  287. return TemplateArgument();
  288. }
  289. llvm_unreachable("Invalid TemplateArgument Kind!");
  290. }
  291. void TemplateArgument::print(const PrintingPolicy &Policy,
  292. raw_ostream &Out) const {
  293. switch (getKind()) {
  294. case Null:
  295. Out << "(no value)";
  296. break;
  297. case Type: {
  298. PrintingPolicy SubPolicy(Policy);
  299. SubPolicy.SuppressStrongLifetime = true;
  300. getAsType().print(Out, SubPolicy);
  301. break;
  302. }
  303. case Declaration: {
  304. NamedDecl *ND = cast<NamedDecl>(getAsDecl());
  305. Out << '&';
  306. if (ND->getDeclName()) {
  307. // FIXME: distinguish between pointer and reference args?
  308. ND->printQualifiedName(Out);
  309. } else {
  310. Out << "(anonymous)";
  311. }
  312. break;
  313. }
  314. case NullPtr:
  315. Out << "nullptr";
  316. break;
  317. case Template:
  318. getAsTemplate().print(Out, Policy);
  319. break;
  320. case TemplateExpansion:
  321. getAsTemplateOrTemplatePattern().print(Out, Policy);
  322. Out << "...";
  323. break;
  324. case Integral: {
  325. printIntegral(*this, Out, Policy);
  326. break;
  327. }
  328. case Expression:
  329. getAsExpr()->printPretty(Out, nullptr, Policy);
  330. break;
  331. case Pack:
  332. Out << "<";
  333. bool First = true;
  334. for (const auto &P : pack_elements()) {
  335. if (First)
  336. First = false;
  337. else
  338. Out << ", ";
  339. P.print(Policy, Out);
  340. }
  341. Out << ">";
  342. break;
  343. }
  344. }
  345. //===----------------------------------------------------------------------===//
  346. // TemplateArgumentLoc Implementation
  347. //===----------------------------------------------------------------------===//
  348. TemplateArgumentLocInfo::TemplateArgumentLocInfo() {
  349. memset((void*)this, 0, sizeof(TemplateArgumentLocInfo));
  350. }
  351. SourceRange TemplateArgumentLoc::getSourceRange() const {
  352. switch (Argument.getKind()) {
  353. case TemplateArgument::Expression:
  354. return getSourceExpression()->getSourceRange();
  355. case TemplateArgument::Declaration:
  356. return getSourceDeclExpression()->getSourceRange();
  357. case TemplateArgument::NullPtr:
  358. return getSourceNullPtrExpression()->getSourceRange();
  359. case TemplateArgument::Type:
  360. if (TypeSourceInfo *TSI = getTypeSourceInfo())
  361. return TSI->getTypeLoc().getSourceRange();
  362. else
  363. return SourceRange();
  364. case TemplateArgument::Template:
  365. if (getTemplateQualifierLoc())
  366. return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
  367. getTemplateNameLoc());
  368. return SourceRange(getTemplateNameLoc());
  369. case TemplateArgument::TemplateExpansion:
  370. if (getTemplateQualifierLoc())
  371. return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
  372. getTemplateEllipsisLoc());
  373. return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
  374. case TemplateArgument::Integral:
  375. return getSourceIntegralExpression()->getSourceRange();
  376. case TemplateArgument::Pack:
  377. case TemplateArgument::Null:
  378. return SourceRange();
  379. }
  380. llvm_unreachable("Invalid TemplateArgument Kind!");
  381. }
  382. const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
  383. const TemplateArgument &Arg) {
  384. switch (Arg.getKind()) {
  385. case TemplateArgument::Null:
  386. // This is bad, but not as bad as crashing because of argument
  387. // count mismatches.
  388. return DB << "(null template argument)";
  389. case TemplateArgument::Type:
  390. return DB << Arg.getAsType();
  391. case TemplateArgument::Declaration:
  392. return DB << Arg.getAsDecl();
  393. case TemplateArgument::NullPtr:
  394. return DB << "nullptr";
  395. case TemplateArgument::Integral:
  396. return DB << Arg.getAsIntegral().toString(10);
  397. case TemplateArgument::Template:
  398. return DB << Arg.getAsTemplate();
  399. case TemplateArgument::TemplateExpansion:
  400. return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
  401. case TemplateArgument::Expression: {
  402. // This shouldn't actually ever happen, so it's okay that we're
  403. // regurgitating an expression here.
  404. // FIXME: We're guessing at LangOptions!
  405. SmallString<32> Str;
  406. llvm::raw_svector_ostream OS(Str);
  407. LangOptions LangOpts;
  408. #ifdef MS_SUPPORT_VARIABLE_LANGOPTS
  409. LangOpts.CPlusPlus = true;
  410. #endif
  411. PrintingPolicy Policy(LangOpts);
  412. Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
  413. return DB << OS.str();
  414. }
  415. case TemplateArgument::Pack: {
  416. // FIXME: We're guessing at LangOptions!
  417. SmallString<32> Str;
  418. llvm::raw_svector_ostream OS(Str);
  419. LangOptions LangOpts;
  420. #ifdef MS_SUPPORT_VARIABLE_LANGOPTS
  421. LangOpts.CPlusPlus = true;
  422. #endif
  423. PrintingPolicy Policy(LangOpts);
  424. Arg.print(Policy, OS);
  425. return DB << OS.str();
  426. }
  427. }
  428. llvm_unreachable("Invalid TemplateArgument Kind!");
  429. }
  430. const ASTTemplateArgumentListInfo *
  431. ASTTemplateArgumentListInfo::Create(ASTContext &C,
  432. const TemplateArgumentListInfo &List) {
  433. assert(llvm::alignOf<ASTTemplateArgumentListInfo>() >=
  434. llvm::alignOf<TemplateArgumentLoc>());
  435. std::size_t size = ASTTemplateArgumentListInfo::sizeFor(List.size());
  436. void *Mem = C.Allocate(size, llvm::alignOf<ASTTemplateArgumentListInfo>());
  437. ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo();
  438. TAI->initializeFrom(List);
  439. return TAI;
  440. }
  441. void ASTTemplateArgumentListInfo::initializeFrom(
  442. const TemplateArgumentListInfo &Info) {
  443. LAngleLoc = Info.getLAngleLoc();
  444. RAngleLoc = Info.getRAngleLoc();
  445. NumTemplateArgs = Info.size();
  446. TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
  447. for (unsigned i = 0; i != NumTemplateArgs; ++i)
  448. new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
  449. }
  450. void ASTTemplateArgumentListInfo::initializeFrom(
  451. const TemplateArgumentListInfo &Info,
  452. bool &Dependent,
  453. bool &InstantiationDependent,
  454. bool &ContainsUnexpandedParameterPack) {
  455. LAngleLoc = Info.getLAngleLoc();
  456. RAngleLoc = Info.getRAngleLoc();
  457. NumTemplateArgs = Info.size();
  458. TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
  459. for (unsigned i = 0; i != NumTemplateArgs; ++i) {
  460. Dependent = Dependent || Info[i].getArgument().isDependent();
  461. InstantiationDependent = InstantiationDependent ||
  462. Info[i].getArgument().isInstantiationDependent();
  463. ContainsUnexpandedParameterPack
  464. = ContainsUnexpandedParameterPack ||
  465. Info[i].getArgument().containsUnexpandedParameterPack();
  466. new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
  467. }
  468. }
  469. void ASTTemplateArgumentListInfo::copyInto(
  470. TemplateArgumentListInfo &Info) const {
  471. Info.setLAngleLoc(LAngleLoc);
  472. Info.setRAngleLoc(RAngleLoc);
  473. for (unsigned I = 0; I != NumTemplateArgs; ++I)
  474. Info.addArgument(getTemplateArgs()[I]);
  475. }
  476. std::size_t ASTTemplateArgumentListInfo::sizeFor(unsigned NumTemplateArgs) {
  477. return sizeof(ASTTemplateArgumentListInfo) +
  478. sizeof(TemplateArgumentLoc) * NumTemplateArgs;
  479. }
  480. void
  481. ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc,
  482. const TemplateArgumentListInfo &Info) {
  483. Base::initializeFrom(Info);
  484. setTemplateKeywordLoc(TemplateKWLoc);
  485. }
  486. void
  487. ASTTemplateKWAndArgsInfo
  488. ::initializeFrom(SourceLocation TemplateKWLoc,
  489. const TemplateArgumentListInfo &Info,
  490. bool &Dependent,
  491. bool &InstantiationDependent,
  492. bool &ContainsUnexpandedParameterPack) {
  493. Base::initializeFrom(Info, Dependent, InstantiationDependent,
  494. ContainsUnexpandedParameterPack);
  495. setTemplateKeywordLoc(TemplateKWLoc);
  496. }
  497. void
  498. ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
  499. // No explicit template arguments, but template keyword loc is valid.
  500. assert(TemplateKWLoc.isValid());
  501. LAngleLoc = SourceLocation();
  502. RAngleLoc = SourceLocation();
  503. NumTemplateArgs = 0;
  504. setTemplateKeywordLoc(TemplateKWLoc);
  505. }
  506. std::size_t
  507. ASTTemplateKWAndArgsInfo::sizeFor(unsigned NumTemplateArgs) {
  508. // Add space for the template keyword location.
  509. // FIXME: There's room for this in the padding before the template args in
  510. // 64-bit builds.
  511. return Base::sizeFor(NumTemplateArgs) + sizeof(SourceLocation);
  512. }