Coverage Report

Created: 2018-07-19 20:53

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/Sema/Template.h
Line
Count
Source (jump to first uncovered line)
1
//===- SemaTemplate.h - C++ Templates ---------------------------*- C++ -*-===//
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
// This file provides types used in the semantic analysis of C++ templates.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_CLANG_SEMA_TEMPLATE_H
14
#define LLVM_CLANG_SEMA_TEMPLATE_H
15
16
#include "clang/AST/DeclTemplate.h"
17
#include "clang/AST/DeclVisitor.h"
18
#include "clang/AST/TemplateBase.h"
19
#include "clang/AST/Type.h"
20
#include "clang/Basic/LLVM.h"
21
#include "clang/Sema/Sema.h"
22
#include "llvm/ADT/ArrayRef.h"
23
#include "llvm/ADT/DenseMap.h"
24
#include "llvm/ADT/PointerUnion.h"
25
#include "llvm/ADT/SmallVector.h"
26
#include <cassert>
27
#include <utility>
28
29
namespace clang {
30
31
class ASTContext;
32
class BindingDecl;
33
class CXXMethodDecl;
34
class Decl;
35
class DeclaratorDecl;
36
class DeclContext;
37
class EnumDecl;
38
class FunctionDecl;
39
class NamedDecl;
40
class ParmVarDecl;
41
class TagDecl;
42
class TypedefNameDecl;
43
class TypeSourceInfo;
44
class VarDecl;
45
46
  /// Data structure that captures multiple levels of template argument
47
  /// lists for use in template instantiation.
48
  ///
49
  /// Multiple levels of template arguments occur when instantiating the 
50
  /// definitions of member templates. For example:
51
  ///
52
  /// \code
53
  /// template<typename T>
54
  /// struct X {
55
  ///   template<T Value>
56
  ///   struct Y {
57
  ///     void f();
58
  ///   };
59
  /// };
60
  /// \endcode
61
  ///
62
  /// When instantiating X<int>::Y<17>::f, the multi-level template argument
63
  /// list will contain a template argument list (int) at depth 0 and a
64
  /// template argument list (17) at depth 1.
65
  class MultiLevelTemplateArgumentList {
66
    /// The template argument list at a certain template depth 
67
    using ArgList = ArrayRef<TemplateArgument>;
68
69
    /// The template argument lists, stored from the innermost template
70
    /// argument list (first) to the outermost template argument list (last).
71
    SmallVector<ArgList, 4> TemplateArgumentLists;
72
73
    /// The number of outer levels of template arguments that are not
74
    /// being substituted.
75
    unsigned NumRetainedOuterLevels = 0;
76
    
77
  public:
78
    /// Construct an empty set of template argument lists.
79
3.41M
    MultiLevelTemplateArgumentList() = default;
80
    
81
    /// Construct a single-level template argument list.
82
    explicit 
83
1.56M
    MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
84
1.56M
      addOuterTemplateArguments(&TemplateArgs);
85
1.56M
    }
86
    
87
    /// Determine the number of levels in this template argument
88
    /// list.
89
16.8M
    unsigned getNumLevels() const {
90
16.8M
      return TemplateArgumentLists.size() + NumRetainedOuterLevels;
91
16.8M
    }
92
93
    /// Determine the number of substituted levels in this template
94
    /// argument list.
95
1.06M
    unsigned getNumSubstitutedLevels() const {
96
1.06M
      return TemplateArgumentLists.size();
97
1.06M
    }
98
99
    /// Retrieve the template argument at a given depth and index.
100
7.99M
    const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
101
7.99M
      assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
102
7.99M
      assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
103
7.99M
      return TemplateArgumentLists[getNumLevels() - Depth - 1][Index];
104
7.99M
    }
105
    
106
    /// Determine whether there is a non-NULL template argument at the
107
    /// given depth and index.
108
    ///
109
    /// There must exist a template argument list at the given depth.
110
4.02M
    bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
111
4.02M
      assert(Depth < getNumLevels());
112
4.02M
113
4.02M
      if (Depth < NumRetainedOuterLevels)
114
19
        return false;
115
4.02M
      
116
4.02M
      if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size())
117
24.8k
        return false;
118
3.99M
      
119
3.99M
      return !(*this)(Depth, Index).isNull();
120
3.99M
    }
121
    
122
    /// Clear out a specific template argument.
123
    void setArgument(unsigned Depth, unsigned Index,
124
536
                     TemplateArgument Arg) {
125
536
      assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
126
536
      assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size());
127
536
      const_cast<TemplateArgument&>(
128
536
                TemplateArgumentLists[getNumLevels() - Depth - 1][Index])
129
536
        = Arg;
130
536
    }
131
    
132
    /// Add a new outermost level to the multi-level template argument 
133
    /// list.
134
4.09M
    void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
135
4.09M
      addOuterTemplateArguments(ArgList(TemplateArgs->data(),
136
4.09M
                                        TemplateArgs->size()));
137
4.09M
    }
138
139
    /// Add a new outmost level to the multi-level template argument
140
    /// list.
141
5.08M
    void addOuterTemplateArguments(ArgList Args) {
142
5.08M
      assert(!NumRetainedOuterLevels &&
143
5.08M
             "substituted args outside retained args?");
144
5.08M
      TemplateArgumentLists.push_back(Args);
145
5.08M
    }
146
147
    /// Add an outermost level that we are not substituting. We have no
148
    /// arguments at this level, and do not remove it from the depth of inner
149
    /// template parameters that we instantiate.
150
46
    void addOuterRetainedLevel() {
151
46
      ++NumRetainedOuterLevels;
152
46
    }
153
154
    /// Retrieve the innermost template argument list.
155
737k
    const ArgList &getInnermost() const {
156
737k
      return TemplateArgumentLists.front(); 
157
737k
    }
158
  };
159
  
160
  /// The context in which partial ordering of function templates occurs.
161
  enum TPOC {
162
    /// Partial ordering of function templates for a function call.
163
    TPOC_Call,
164
165
    /// Partial ordering of function templates for a call to a 
166
    /// conversion function.
167
    TPOC_Conversion,
168
169
    /// Partial ordering of function templates in other contexts, e.g.,
170
    /// taking the address of a function template or matching a function 
171
    /// template specialization to a function template.
172
    TPOC_Other
173
  };
174
175
  // This is lame but unavoidable in a world without forward
176
  // declarations of enums.  The alternatives are to either pollute
177
  // Sema.h (by including this file) or sacrifice type safety (by
178
  // making Sema.h declare things as enums).
179
  class TemplatePartialOrderingContext {
180
    TPOC Value;
181
182
  public:
183
23.9k
    TemplatePartialOrderingContext(TPOC Value) : Value(Value) {}
184
185
48.9k
    operator TPOC() const { return Value; }
186
  };
187
188
  /// Captures a template argument whose value has been deduced
189
  /// via c++ template argument deduction.
190
  class DeducedTemplateArgument : public TemplateArgument {
191
    /// For a non-type template argument, whether the value was
192
    /// deduced from an array bound.
193
    bool DeducedFromArrayBound = false;
194
195
  public:
196
4.24M
    DeducedTemplateArgument() = default;
197
198
    DeducedTemplateArgument(const TemplateArgument &Arg,
199
                            bool DeducedFromArrayBound = false)
200
2.06M
        : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) {}
201
202
    /// Construct an integral non-type template argument that
203
    /// has been deduced, possibly from an array bound.
204
    DeducedTemplateArgument(ASTContext &Ctx,
205
                            const llvm::APSInt &Value,
206
                            QualType ValueType,
207
                            bool DeducedFromArrayBound)
208
        : TemplateArgument(Ctx, Value, ValueType),
209
139k
          DeducedFromArrayBound(DeducedFromArrayBound) {}
210
211
    /// For a non-type template argument, determine whether the
212
    /// template argument was deduced from an array bound.
213
1.37M
    bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
214
215
    /// Specify whether the given non-type template argument
216
    /// was deduced from an array bound.
217
131k
    void setDeducedFromArrayBound(bool Deduced) {
218
131k
      DeducedFromArrayBound = Deduced;
219
131k
    }
220
  };
221
222
  /// A stack-allocated class that identifies which local
223
  /// variable declaration instantiations are present in this scope.
224
  ///
225
  /// A new instance of this class type will be created whenever we
226
  /// instantiate a new function declaration, which will have its own
227
  /// set of parameter declarations.
228
  class LocalInstantiationScope {
229
  public:
230
    /// A set of declarations.
231
    using DeclArgumentPack = SmallVector<ParmVarDecl *, 4>;
232
233
  private:
234
    /// Reference to the semantic analysis that is performing
235
    /// this template instantiation.
236
    Sema &SemaRef;
237
238
    using LocalDeclsMap =
239
        llvm::SmallDenseMap<const Decl *,
240
                            llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>;
241
242
    /// A mapping from local declarations that occur
243
    /// within a template to their instantiations.
244
    ///
245
    /// This mapping is used during instantiation to keep track of,
246
    /// e.g., function parameter and variable declarations. For example,
247
    /// given:
248
    ///
249
    /// \code
250
    ///   template<typename T> T add(T x, T y) { return x + y; }
251
    /// \endcode
252
    ///
253
    /// when we instantiate add<int>, we will introduce a mapping from
254
    /// the ParmVarDecl for 'x' that occurs in the template to the
255
    /// instantiated ParmVarDecl for 'x'.
256
    ///
257
    /// For a parameter pack, the local instantiation scope may contain a
258
    /// set of instantiated parameters. This is stored as a DeclArgumentPack
259
    /// pointer.
260
    LocalDeclsMap LocalDecls;
261
262
    /// The set of argument packs we've allocated.
263
    SmallVector<DeclArgumentPack *, 1> ArgumentPacks;
264
    
265
    /// The outer scope, which contains local variable
266
    /// definitions from some other instantiation (that may not be
267
    /// relevant to this particular scope).
268
    LocalInstantiationScope *Outer;
269
270
    /// Whether we have already exited this scope.
271
    bool Exited = false;
272
273
    /// Whether to combine this scope with the outer scope, such that
274
    /// lookup will search our outer scope.
275
    bool CombineWithOuterScope;
276
    
277
    /// If non-NULL, the template parameter pack that has been
278
    /// partially substituted per C++0x [temp.arg.explicit]p9.
279
    NamedDecl *PartiallySubstitutedPack = nullptr;
280
    
281
    /// If \c PartiallySubstitutedPack is non-null, the set of
282
    /// explicitly-specified template arguments in that pack.
283
    const TemplateArgument *ArgsInPartiallySubstitutedPack;    
284
    
285
    /// If \c PartiallySubstitutedPack, the number of 
286
    /// explicitly-specified template arguments in 
287
    /// ArgsInPartiallySubstitutedPack.
288
    unsigned NumArgsInPartiallySubstitutedPack;
289
290
  public:
291
    LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
292
        : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
293
11.5M
          CombineWithOuterScope(CombineWithOuterScope) {
294
11.5M
      SemaRef.CurrentInstantiationScope = this;
295
11.5M
    }
296
297
    LocalInstantiationScope(const LocalInstantiationScope &) = delete;
298
    LocalInstantiationScope &
299
    operator=(const LocalInstantiationScope &) = delete;
300
301
11.5M
    ~LocalInstantiationScope() {
302
11.5M
      Exit();
303
11.5M
    }
304
    
305
    const Sema &getSema() const { return SemaRef; }
306
307
    /// Exit this local instantiation scope early.
308
11.8M
    void Exit() {
309
11.8M
      if (Exited)
310
263k
        return;
311
11.5M
      
312
11.6M
      
for (unsigned I = 0, N = ArgumentPacks.size(); 11.5M
I != N;
++I22.4k
)
313
22.4k
        delete ArgumentPacks[I];
314
11.5M
        
315
11.5M
      SemaRef.CurrentInstantiationScope = Outer;
316
11.5M
      Exited = true;
317
11.5M
    }
318
319
    /// Clone this scope, and all outer scopes, down to the given
320
    /// outermost scope.
321
134
    LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) {
322
134
      if (this == Outermost) 
return this74
;
323
60
324
60
      // Save the current scope from SemaRef since the LocalInstantiationScope
325
60
      // will overwrite it on construction
326
60
      LocalInstantiationScope *oldScope = SemaRef.CurrentInstantiationScope;
327
60
328
60
      LocalInstantiationScope *newScope =
329
60
        new LocalInstantiationScope(SemaRef, CombineWithOuterScope);
330
60
331
60
      newScope->Outer = nullptr;
332
60
      if (Outer)
333
60
        newScope->Outer = Outer->cloneScopes(Outermost);
334
60
335
60
      newScope->PartiallySubstitutedPack = PartiallySubstitutedPack;
336
60
      newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack;
337
60
      newScope->NumArgsInPartiallySubstitutedPack =
338
60
        NumArgsInPartiallySubstitutedPack;
339
60
340
60
      for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end();
341
96
           I != E; 
++I36
) {
342
36
        const Decl *D = I->first;
343
36
        llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored =
344
36
          newScope->LocalDecls[D];
345
36
        if (I->second.is<Decl *>()) {
346
36
          Stored = I->second.get<Decl *>();
347
36
        } else {
348
0
          DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>();
349
0
          DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack);
350
0
          Stored = NewPack;
351
0
          newScope->ArgumentPacks.push_back(NewPack);
352
0
        }
353
36
      }
354
60
      // Restore the saved scope to SemaRef
355
60
      SemaRef.CurrentInstantiationScope = oldScope;
356
60
      return newScope;
357
60
    }
358
359
    /// deletes the given scope, and all otuer scopes, down to the
360
    /// given outermost scope.
361
    static void deleteScopes(LocalInstantiationScope *Scope,
362
74
                             LocalInstantiationScope *Outermost) {
363
134
      while (Scope && Scope != Outermost) {
364
60
        LocalInstantiationScope *Out = Scope->Outer;
365
60
        delete Scope;
366
60
        Scope = Out;
367
60
      }
368
74
    }
369
370
    /// Find the instantiation of the declaration D within the current
371
    /// instantiation scope.
372
    ///
373
    /// \param D The declaration whose instantiation we are searching for.
374
    ///
375
    /// \returns A pointer to the declaration or argument pack of declarations
376
    /// to which the declaration \c D is instantiated, if found. Otherwise,
377
    /// returns NULL.
378
    llvm::PointerUnion<Decl *, DeclArgumentPack *> *
379
    findInstantiationOf(const Decl *D);
380
381
    void InstantiatedLocal(const Decl *D, Decl *Inst);
382
    void InstantiatedLocalPackArg(const Decl *D, ParmVarDecl *Inst);
383
    void MakeInstantiatedLocalArgPack(const Decl *D);
384
    
385
    /// Note that the given parameter pack has been partially substituted
386
    /// via explicit specification of template arguments 
387
    /// (C++0x [temp.arg.explicit]p9).
388
    ///
389
    /// \param Pack The parameter pack, which will always be a template
390
    /// parameter pack.
391
    ///
392
    /// \param ExplicitArgs The explicitly-specified template arguments provided
393
    /// for this parameter pack.
394
    ///
395
    /// \param NumExplicitArgs The number of explicitly-specified template
396
    /// arguments provided for this parameter pack.
397
    void SetPartiallySubstitutedPack(NamedDecl *Pack, 
398
                                     const TemplateArgument *ExplicitArgs,
399
                                     unsigned NumExplicitArgs);
400
401
    /// Reset the partially-substituted pack when it is no longer of
402
    /// interest.
403
4.64k
    void ResetPartiallySubstitutedPack() {
404
4.64k
      assert(PartiallySubstitutedPack && "No partially-substituted pack");
405
4.64k
      PartiallySubstitutedPack = nullptr;
406
4.64k
      ArgsInPartiallySubstitutedPack = nullptr;
407
4.64k
      NumArgsInPartiallySubstitutedPack = 0;
408
4.64k
    }
409
410
    /// Retrieve the partially-substitued template parameter pack.
411
    ///
412
    /// If there is no partially-substituted parameter pack, returns NULL.
413
    NamedDecl *
414
    getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr,
415
                                unsigned *NumExplicitArgs = nullptr) const;
416
  };
417
418
  class TemplateDeclInstantiator
419
    : public DeclVisitor<TemplateDeclInstantiator, Decl *> 
420
  {
421
    Sema &SemaRef;
422
    Sema::ArgumentPackSubstitutionIndexRAII SubstIndex;
423
    DeclContext *Owner;
424
    const MultiLevelTemplateArgumentList &TemplateArgs;
425
    Sema::LateInstantiatedAttrVec* LateAttrs = nullptr;
426
    LocalInstantiationScope *StartingScope = nullptr;
427
428
    /// A list of out-of-line class template partial
429
    /// specializations that will need to be instantiated after the
430
    /// enclosing class's instantiation is complete.
431
    SmallVector<std::pair<ClassTemplateDecl *,
432
                                ClassTemplatePartialSpecializationDecl *>, 4>
433
      OutOfLinePartialSpecs;
434
435
    /// A list of out-of-line variable template partial
436
    /// specializations that will need to be instantiated after the
437
    /// enclosing variable's instantiation is complete.
438
    /// FIXME: Verify that this is needed.
439
    SmallVector<
440
        std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4>
441
    OutOfLineVarPartialSpecs;
442
443
  public:
444
    TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
445
                             const MultiLevelTemplateArgumentList &TemplateArgs)
446
        : SemaRef(SemaRef),
447
          SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
448
1.51M
          Owner(Owner), TemplateArgs(TemplateArgs) {}
449
450
// Define all the decl visitors using DeclNodes.inc
451
#define DECL(DERIVED, BASE) \
452
    Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D);
453
#define ABSTRACT_DECL(DECL)
454
455
// Decls which never appear inside a class or function.
456
#define OBJCCONTAINER(DERIVED, BASE)
457
#define FILESCOPEASM(DERIVED, BASE)
458
#define IMPORT(DERIVED, BASE)
459
#define EXPORT(DERIVED, BASE)
460
#define LINKAGESPEC(DERIVED, BASE)
461
#define OBJCCOMPATIBLEALIAS(DERIVED, BASE)
462
#define OBJCMETHOD(DERIVED, BASE)
463
#define OBJCTYPEPARAM(DERIVED, BASE)
464
#define OBJCIVAR(DERIVED, BASE)
465
#define OBJCPROPERTY(DERIVED, BASE)
466
#define OBJCPROPERTYIMPL(DERIVED, BASE)
467
#define EMPTY(DERIVED, BASE)
468
469
// Decls which use special-case instantiation code.
470
#define BLOCK(DERIVED, BASE)
471
#define CAPTURED(DERIVED, BASE)
472
#define IMPLICITPARAM(DERIVED, BASE)
473
474
#include "clang/AST/DeclNodes.inc"
475
476
    // A few supplemental visitor functions.
477
    Decl *VisitCXXMethodDecl(CXXMethodDecl *D,
478
                             TemplateParameterList *TemplateParams,
479
                             bool IsClassScopeSpecialization = false);
480
    Decl *VisitFunctionDecl(FunctionDecl *D,
481
                            TemplateParameterList *TemplateParams);
482
    Decl *VisitDecl(Decl *D);
483
    Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate,
484
                       ArrayRef<BindingDecl *> *Bindings = nullptr);
485
486
    // Enable late instantiation of attributes.  Late instantiated attributes
487
    // will be stored in LA.
488
822k
    void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) {
489
822k
      LateAttrs = LA;
490
822k
      StartingScope = SemaRef.CurrentInstantiationScope;
491
822k
    }
492
493
    // Disable late instantiation of attributes.
494
822k
    void disableLateAttributeInstantiation() {
495
822k
      LateAttrs = nullptr;
496
822k
      StartingScope = nullptr;
497
822k
    }
498
499
74
    LocalInstantiationScope *getStartingScope() const { return StartingScope; }
500
501
    using delayed_partial_spec_iterator = SmallVectorImpl<std::pair<
502
      ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *>>::iterator;
503
504
    using delayed_var_partial_spec_iterator = SmallVectorImpl<std::pair<
505
        VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>>::iterator;
506
507
    /// Return an iterator to the beginning of the set of
508
    /// "delayed" partial specializations, which must be passed to
509
    /// InstantiateClassTemplatePartialSpecialization once the class
510
    /// definition has been completed.
511
820k
    delayed_partial_spec_iterator delayed_partial_spec_begin() {
512
820k
      return OutOfLinePartialSpecs.begin();
513
820k
    }
514
515
820k
    delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() {
516
820k
      return OutOfLineVarPartialSpecs.begin();
517
820k
    }
518
519
    /// Return an iterator to the end of the set of
520
    /// "delayed" partial specializations, which must be passed to
521
    /// InstantiateClassTemplatePartialSpecialization once the class
522
    /// definition has been completed.
523
820k
    delayed_partial_spec_iterator delayed_partial_spec_end() {
524
820k
      return OutOfLinePartialSpecs.end();
525
820k
    }
526
527
820k
    delayed_var_partial_spec_iterator delayed_var_partial_spec_end() {
528
820k
      return OutOfLineVarPartialSpecs.end();
529
820k
    }
530
531
    // Helper functions for instantiating methods.
532
    TypeSourceInfo *SubstFunctionType(FunctionDecl *D,
533
                             SmallVectorImpl<ParmVarDecl *> &Params);
534
    bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl);
535
    bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl);
536
537
    TemplateParameterList *
538
      SubstTemplateParams(TemplateParameterList *List);
539
540
    bool SubstQualifier(const DeclaratorDecl *OldDecl,
541
                        DeclaratorDecl *NewDecl);
542
    bool SubstQualifier(const TagDecl *OldDecl,
543
                        TagDecl *NewDecl);
544
545
    Decl *VisitVarTemplateSpecializationDecl(
546
        VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos,
547
        const TemplateArgumentListInfo &TemplateArgsInfo,
548
        ArrayRef<TemplateArgument> Converted);
549
550
    Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
551
    ClassTemplatePartialSpecializationDecl *
552
    InstantiateClassTemplatePartialSpecialization(
553
                                              ClassTemplateDecl *ClassTemplate,
554
                           ClassTemplatePartialSpecializationDecl *PartialSpec);
555
    VarTemplatePartialSpecializationDecl *
556
    InstantiateVarTemplatePartialSpecialization(
557
        VarTemplateDecl *VarTemplate,
558
        VarTemplatePartialSpecializationDecl *PartialSpec);
559
    void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern);
560
561
  private:
562
    template<typename T>
563
    Decl *instantiateUnresolvedUsingDecl(T *D,
564
                                         bool InstantiatingPackElement = false);
565
  };  
566
567
} // namespace clang
568
569
#endif // LLVM_CLANG_SEMA_TEMPLATE_H