DeclTemplate.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. //===--- DeclCXX.cpp - C++ Declaration AST Node 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 the C++ related Decl classes for templates.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "clang/AST/DeclCXX.h"
  14. #include "clang/AST/DeclTemplate.h"
  15. #include "clang/AST/Expr.h"
  16. #include "clang/AST/ASTContext.h"
  17. #include "clang/Basic/IdentifierTable.h"
  18. #include "llvm/ADT/STLExtras.h"
  19. using namespace clang;
  20. //===----------------------------------------------------------------------===//
  21. // TemplateParameterList Implementation
  22. //===----------------------------------------------------------------------===//
  23. TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
  24. SourceLocation LAngleLoc,
  25. Decl **Params, unsigned NumParams,
  26. SourceLocation RAngleLoc)
  27. : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
  28. NumParams(NumParams) {
  29. for (unsigned Idx = 0; Idx < NumParams; ++Idx)
  30. begin()[Idx] = Params[Idx];
  31. }
  32. TemplateParameterList *
  33. TemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc,
  34. SourceLocation LAngleLoc, Decl **Params,
  35. unsigned NumParams, SourceLocation RAngleLoc) {
  36. unsigned Size = sizeof(TemplateParameterList) + sizeof(Decl *) * NumParams;
  37. unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment;
  38. void *Mem = C.Allocate(Size, Align);
  39. return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
  40. NumParams, RAngleLoc);
  41. }
  42. unsigned TemplateParameterList::getMinRequiredArguments() const {
  43. unsigned NumRequiredArgs = size();
  44. iterator Param = const_cast<TemplateParameterList *>(this)->end(),
  45. ParamBegin = const_cast<TemplateParameterList *>(this)->begin();
  46. while (Param != ParamBegin) {
  47. --Param;
  48. if (!(*Param)->isTemplateParameterPack() &&
  49. !(isa<TemplateTypeParmDecl>(*Param) &&
  50. cast<TemplateTypeParmDecl>(*Param)->hasDefaultArgument()) &&
  51. !(isa<NonTypeTemplateParmDecl>(*Param) &&
  52. cast<NonTypeTemplateParmDecl>(*Param)->hasDefaultArgument()) &&
  53. !(isa<TemplateTemplateParmDecl>(*Param) &&
  54. cast<TemplateTemplateParmDecl>(*Param)->hasDefaultArgument()))
  55. break;
  56. --NumRequiredArgs;
  57. }
  58. return NumRequiredArgs;
  59. }
  60. //===----------------------------------------------------------------------===//
  61. // TemplateDecl Implementation
  62. //===----------------------------------------------------------------------===//
  63. TemplateDecl::~TemplateDecl() {
  64. }
  65. //===----------------------------------------------------------------------===//
  66. // FunctionTemplateDecl Implementation
  67. //===----------------------------------------------------------------------===//
  68. FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
  69. DeclContext *DC,
  70. SourceLocation L,
  71. DeclarationName Name,
  72. TemplateParameterList *Params,
  73. NamedDecl *Decl) {
  74. return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
  75. }
  76. //===----------------------------------------------------------------------===//
  77. // ClassTemplateDecl Implementation
  78. //===----------------------------------------------------------------------===//
  79. ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
  80. DeclContext *DC,
  81. SourceLocation L,
  82. DeclarationName Name,
  83. TemplateParameterList *Params,
  84. NamedDecl *Decl,
  85. ClassTemplateDecl *PrevDecl) {
  86. Common *CommonPtr;
  87. if (PrevDecl)
  88. CommonPtr = PrevDecl->CommonPtr;
  89. else
  90. CommonPtr = new (C) Common;
  91. return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl,
  92. CommonPtr);
  93. }
  94. ClassTemplateDecl::~ClassTemplateDecl() {
  95. assert(CommonPtr == 0 && "ClassTemplateDecl must be explicitly destroyed");
  96. }
  97. void ClassTemplateDecl::Destroy(ASTContext& C) {
  98. if (!PreviousDeclaration) {
  99. CommonPtr->~Common();
  100. C.Deallocate((void*)CommonPtr);
  101. }
  102. CommonPtr = 0;
  103. this->~ClassTemplateDecl();
  104. C.Deallocate((void*)this);
  105. }
  106. QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
  107. if (!CommonPtr->InjectedClassNameType.isNull())
  108. return CommonPtr->InjectedClassNameType;
  109. // FIXME: n2800 14.6.1p1 should say how the template arguments
  110. // corresponding to template parameter packs should be pack
  111. // expansions. We already say that in 14.6.2.1p2, so it would be
  112. // better to fix that redundancy.
  113. TemplateParameterList *Params = getTemplateParameters();
  114. llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
  115. llvm::SmallVector<TemplateArgument, 16> CanonTemplateArgs;
  116. TemplateArgs.reserve(Params->size());
  117. CanonTemplateArgs.reserve(Params->size());
  118. for (TemplateParameterList::iterator
  119. Param = Params->begin(), ParamEnd = Params->end();
  120. Param != ParamEnd; ++Param) {
  121. if (isa<TemplateTypeParmDecl>(*Param)) {
  122. QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param));
  123. TemplateArgs.push_back(TemplateArgument((*Param)->getLocation(),
  124. ParamType));
  125. CanonTemplateArgs.push_back(
  126. TemplateArgument((*Param)->getLocation(),
  127. Context.getCanonicalType(ParamType)));
  128. } else if (NonTypeTemplateParmDecl *NTTP =
  129. dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
  130. // FIXME: Build canonical expression, too!
  131. Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(),
  132. NTTP->getLocation(),
  133. NTTP->getType()->isDependentType(),
  134. /*Value-dependent=*/true);
  135. TemplateArgs.push_back(TemplateArgument(E));
  136. CanonTemplateArgs.push_back(TemplateArgument(E));
  137. } else {
  138. TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
  139. TemplateArgs.push_back(TemplateArgument(TTP->getLocation(), TTP));
  140. CanonTemplateArgs.push_back(TemplateArgument(TTP->getLocation(),
  141. Context.getCanonicalDecl(TTP)));
  142. }
  143. }
  144. // FIXME: I should really move the "build-the-canonical-type" logic
  145. // into ASTContext::getTemplateSpecializationType.
  146. TemplateName Name = TemplateName(this);
  147. QualType CanonType = Context.getTemplateSpecializationType(
  148. Context.getCanonicalTemplateName(Name),
  149. &CanonTemplateArgs[0],
  150. CanonTemplateArgs.size());
  151. CommonPtr->InjectedClassNameType
  152. = Context.getTemplateSpecializationType(Name,
  153. &TemplateArgs[0],
  154. TemplateArgs.size(),
  155. CanonType);
  156. return CommonPtr->InjectedClassNameType;
  157. }
  158. //===----------------------------------------------------------------------===//
  159. // TemplateTypeParm Allocation/Deallocation Method Implementations
  160. //===----------------------------------------------------------------------===//
  161. TemplateTypeParmDecl *
  162. TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
  163. SourceLocation L, unsigned D, unsigned P,
  164. IdentifierInfo *Id, bool Typename,
  165. bool ParameterPack) {
  166. QualType Type = C.getTemplateTypeParmType(D, P, Id);
  167. return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack);
  168. }
  169. //===----------------------------------------------------------------------===//
  170. // NonTypeTemplateParmDecl Method Implementations
  171. //===----------------------------------------------------------------------===//
  172. NonTypeTemplateParmDecl *
  173. NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
  174. SourceLocation L, unsigned D, unsigned P,
  175. IdentifierInfo *Id, QualType T,
  176. SourceLocation TypeSpecStartLoc) {
  177. return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T,
  178. TypeSpecStartLoc);
  179. }
  180. SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
  181. return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
  182. : SourceLocation();
  183. }
  184. //===----------------------------------------------------------------------===//
  185. // TemplateTemplateParmDecl Method Implementations
  186. //===----------------------------------------------------------------------===//
  187. TemplateTemplateParmDecl *
  188. TemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
  189. SourceLocation L, unsigned D, unsigned P,
  190. IdentifierInfo *Id,
  191. TemplateParameterList *Params) {
  192. return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params);
  193. }
  194. SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
  195. return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
  196. : SourceLocation();
  197. }
  198. //===----------------------------------------------------------------------===//
  199. // TemplateArgument Implementation
  200. //===----------------------------------------------------------------------===//
  201. TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) {
  202. TypeOrValue = reinterpret_cast<uintptr_t>(E);
  203. StartLoc = E->getSourceRange().getBegin();
  204. }
  205. //===----------------------------------------------------------------------===//
  206. // TemplateArgumentListBuilder Implementation
  207. //===----------------------------------------------------------------------===//
  208. void TemplateArgumentListBuilder::push_back(const TemplateArgument& Arg) {
  209. switch (Arg.getKind()) {
  210. default: break;
  211. case TemplateArgument::Type:
  212. assert(Arg.getAsType()->isCanonical() && "Type must be canonical!");
  213. break;
  214. }
  215. if (!isAddingFromParameterPack()) {
  216. // Add begin and end indicies.
  217. Indices.push_back(Args.size());
  218. Indices.push_back(Args.size());
  219. }
  220. Args.push_back(Arg);
  221. }
  222. void TemplateArgumentListBuilder::BeginParameterPack() {
  223. assert(!isAddingFromParameterPack() && "Already adding to parameter pack!");
  224. Indices.push_back(Args.size());
  225. }
  226. void TemplateArgumentListBuilder::EndParameterPack() {
  227. assert(isAddingFromParameterPack() && "Not adding to parameter pack!");
  228. Indices.push_back(Args.size());
  229. }
  230. //===----------------------------------------------------------------------===//
  231. // TemplateArgumentList Implementation
  232. //===----------------------------------------------------------------------===//
  233. TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
  234. TemplateArgumentListBuilder &Builder,
  235. bool CopyArgs, bool FlattenArgs)
  236. : NumArguments(Builder.flatSize()) {
  237. if (!CopyArgs) {
  238. Arguments.setPointer(Builder.getFlatArgumentList());
  239. Arguments.setInt(1);
  240. return;
  241. }
  242. unsigned Size = sizeof(TemplateArgument) * Builder.flatSize();
  243. unsigned Align = llvm::AlignOf<TemplateArgument>::Alignment;
  244. void *Mem = Context.Allocate(Size, Align);
  245. Arguments.setPointer((TemplateArgument *)Mem);
  246. Arguments.setInt(0);
  247. TemplateArgument *Args = (TemplateArgument *)Mem;
  248. for (unsigned I = 0; I != NumArguments; ++I)
  249. new (Args + I) TemplateArgument(Builder.getFlatArgumentList()[I]);
  250. }
  251. TemplateArgumentList::~TemplateArgumentList() {
  252. // FIXME: Deallocate template arguments
  253. }
  254. //===----------------------------------------------------------------------===//
  255. // ClassTemplateSpecializationDecl Implementation
  256. //===----------------------------------------------------------------------===//
  257. ClassTemplateSpecializationDecl::
  258. ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
  259. DeclContext *DC, SourceLocation L,
  260. ClassTemplateDecl *SpecializedTemplate,
  261. TemplateArgumentListBuilder &Builder)
  262. : CXXRecordDecl(DK,
  263. SpecializedTemplate->getTemplatedDecl()->getTagKind(),
  264. DC, L,
  265. // FIXME: Should we use DeclarationName for the name of
  266. // class template specializations?
  267. SpecializedTemplate->getIdentifier()),
  268. SpecializedTemplate(SpecializedTemplate),
  269. TemplateArgs(Context, Builder, /*CopyArgs=*/true, /*FlattenArgs=*/true),
  270. SpecializationKind(TSK_Undeclared) {
  271. }
  272. ClassTemplateSpecializationDecl *
  273. ClassTemplateSpecializationDecl::Create(ASTContext &Context,
  274. DeclContext *DC, SourceLocation L,
  275. ClassTemplateDecl *SpecializedTemplate,
  276. TemplateArgumentListBuilder &Builder,
  277. ClassTemplateSpecializationDecl *PrevDecl) {
  278. ClassTemplateSpecializationDecl *Result
  279. = new (Context)ClassTemplateSpecializationDecl(Context,
  280. ClassTemplateSpecialization,
  281. DC, L,
  282. SpecializedTemplate,
  283. Builder);
  284. Context.getTypeDeclType(Result, PrevDecl);
  285. return Result;
  286. }
  287. //===----------------------------------------------------------------------===//
  288. // ClassTemplatePartialSpecializationDecl Implementation
  289. //===----------------------------------------------------------------------===//
  290. ClassTemplatePartialSpecializationDecl *
  291. ClassTemplatePartialSpecializationDecl::
  292. Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
  293. TemplateParameterList *Params,
  294. ClassTemplateDecl *SpecializedTemplate,
  295. TemplateArgumentListBuilder &Builder,
  296. ClassTemplatePartialSpecializationDecl *PrevDecl) {
  297. ClassTemplatePartialSpecializationDecl *Result
  298. = new (Context)ClassTemplatePartialSpecializationDecl(Context,
  299. DC, L, Params,
  300. SpecializedTemplate,
  301. Builder);
  302. Result->setSpecializationKind(TSK_ExplicitSpecialization);
  303. Context.getTypeDeclType(Result, PrevDecl);
  304. return Result;
  305. }