TemplateName.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. //===--- TemplateName.cpp - C++ Template Name Representation---------------===//
  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 defines the TemplateName interface and subclasses.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "clang/AST/TemplateName.h"
  14. #include "clang/AST/DeclTemplate.h"
  15. #include "clang/AST/NestedNameSpecifier.h"
  16. #include "clang/AST/PrettyPrinter.h"
  17. #include "clang/AST/TemplateBase.h"
  18. #include "clang/Basic/Diagnostic.h"
  19. #include "clang/Basic/LangOptions.h"
  20. #include "llvm/Support/raw_ostream.h"
  21. using namespace clang;
  22. using namespace llvm;
  23. TemplateArgument
  24. SubstTemplateTemplateParmPackStorage::getArgumentPack() const {
  25. return TemplateArgument(Arguments, size());
  26. }
  27. void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
  28. Profile(ID, Parameter, Replacement);
  29. }
  30. void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID,
  31. TemplateTemplateParmDecl *parameter,
  32. TemplateName replacement) {
  33. ID.AddPointer(parameter);
  34. ID.AddPointer(replacement.getAsVoidPointer());
  35. }
  36. void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
  37. ASTContext &Context) {
  38. Profile(ID, Context, Parameter, TemplateArgument(Arguments, size()));
  39. }
  40. void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
  41. ASTContext &Context,
  42. TemplateTemplateParmDecl *Parameter,
  43. const TemplateArgument &ArgPack) {
  44. ID.AddPointer(Parameter);
  45. ArgPack.Profile(ID, Context);
  46. }
  47. TemplateName::NameKind TemplateName::getKind() const {
  48. if (Storage.is<TemplateDecl *>())
  49. return Template;
  50. if (Storage.is<DependentTemplateName *>())
  51. return DependentTemplate;
  52. if (Storage.is<QualifiedTemplateName *>())
  53. return QualifiedTemplate;
  54. UncommonTemplateNameStorage *uncommon
  55. = Storage.get<UncommonTemplateNameStorage*>();
  56. if (uncommon->getAsOverloadedStorage())
  57. return OverloadedTemplate;
  58. if (uncommon->getAsSubstTemplateTemplateParm())
  59. return SubstTemplateTemplateParm;
  60. return SubstTemplateTemplateParmPack;
  61. }
  62. TemplateDecl *TemplateName::getAsTemplateDecl() const {
  63. if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
  64. return Template;
  65. if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
  66. return QTN->getTemplateDecl();
  67. if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
  68. return sub->getReplacement().getAsTemplateDecl();
  69. return nullptr;
  70. }
  71. bool TemplateName::isDependent() const {
  72. if (TemplateDecl *Template = getAsTemplateDecl()) {
  73. if (isa<TemplateTemplateParmDecl>(Template))
  74. return true;
  75. // FIXME: Hack, getDeclContext() can be null if Template is still
  76. // initializing due to PCH reading, so we check it before using it.
  77. // Should probably modify TemplateSpecializationType to allow constructing
  78. // it without the isDependent() checking.
  79. return Template->getDeclContext() &&
  80. Template->getDeclContext()->isDependentContext();
  81. }
  82. assert(!getAsOverloadedTemplate() &&
  83. "overloaded templates shouldn't survive to here");
  84. return true;
  85. }
  86. bool TemplateName::isInstantiationDependent() const {
  87. if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
  88. if (QTN->getQualifier()->isInstantiationDependent())
  89. return true;
  90. }
  91. return isDependent();
  92. }
  93. bool TemplateName::containsUnexpandedParameterPack() const {
  94. if (TemplateDecl *Template = getAsTemplateDecl()) {
  95. if (TemplateTemplateParmDecl *TTP
  96. = dyn_cast<TemplateTemplateParmDecl>(Template))
  97. return TTP->isParameterPack();
  98. return false;
  99. }
  100. if (DependentTemplateName *DTN = getAsDependentTemplateName())
  101. return DTN->getQualifier() &&
  102. DTN->getQualifier()->containsUnexpandedParameterPack();
  103. return getAsSubstTemplateTemplateParmPack() != nullptr;
  104. }
  105. void
  106. TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
  107. bool SuppressNNS) const {
  108. if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
  109. OS << *Template;
  110. else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
  111. if (!SuppressNNS)
  112. QTN->getQualifier()->print(OS, Policy);
  113. if (QTN->hasTemplateKeyword())
  114. OS << "template ";
  115. OS << *QTN->getDecl();
  116. } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
  117. if (!SuppressNNS && DTN->getQualifier())
  118. DTN->getQualifier()->print(OS, Policy);
  119. OS << "template ";
  120. if (DTN->isIdentifier())
  121. OS << DTN->getIdentifier()->getName();
  122. else
  123. OS << "operator " << getOperatorSpelling(DTN->getOperator());
  124. } else if (SubstTemplateTemplateParmStorage *subst
  125. = getAsSubstTemplateTemplateParm()) {
  126. subst->getReplacement().print(OS, Policy, SuppressNNS);
  127. } else if (SubstTemplateTemplateParmPackStorage *SubstPack
  128. = getAsSubstTemplateTemplateParmPack())
  129. OS << *SubstPack->getParameterPack();
  130. else {
  131. OverloadedTemplateStorage *OTS = getAsOverloadedTemplate();
  132. (*OTS->begin())->printName(OS);
  133. }
  134. }
  135. const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
  136. TemplateName N) {
  137. std::string NameStr;
  138. raw_string_ostream OS(NameStr);
  139. LangOptions LO;
  140. #ifdef MS_SUPPORT_VARIABLE_LANGOPTS
  141. LO.CPlusPlus = true;
  142. LO.Bool = true;
  143. #endif
  144. OS << '\'';
  145. N.print(OS, PrintingPolicy(LO));
  146. OS << '\'';
  147. OS.flush();
  148. return DB << NameStr;
  149. }
  150. void TemplateName::dump(raw_ostream &OS) const {
  151. LangOptions LO; // FIXME!
  152. #ifdef MS_SUPPORT_VARIABLE_LANGOPTS
  153. LO.CPlusPlus = true;
  154. LO.Bool = true;
  155. #endif
  156. print(OS, PrintingPolicy(LO));
  157. }
  158. void TemplateName::dump() const {
  159. dump(llvm::errs());
  160. }