Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h
Line
Count
Source
1
//===--- ParsedTemplate.h - Template Parsing Data Types ---------*- 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
//
10
//  This file provides data structures that store the parsed representation of
11
//  templates.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
16
#define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
17
18
#include "clang/Basic/OperatorKinds.h"
19
#include "clang/Basic/SourceLocation.h"
20
#include "clang/Basic/TemplateKinds.h"
21
#include "clang/Sema/DeclSpec.h"
22
#include "clang/Sema/Ownership.h"
23
#include "llvm/ADT/SmallVector.h"
24
#include <cassert>
25
#include <cstdlib>
26
#include <new>
27
28
namespace clang {  
29
  /// \brief Represents the parsed form of a C++ template argument.
30
  class ParsedTemplateArgument {
31
  public:
32
    /// \brief Describes the kind of template argument that was parsed.
33
    enum KindType {
34
      /// \brief A template type parameter, stored as a type.
35
      Type,
36
      /// \brief A non-type template parameter, stored as an expression.
37
      NonType,
38
      /// \brief A template template argument, stored as a template name.
39
      Template
40
    };
41
42
    /// \brief Build an empty template argument. 
43
    ///
44
    /// This template argument is invalid.
45
47.8k
    ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
46
    
47
    /// \brief Create a template type argument or non-type template argument.
48
    ///
49
    /// \param Arg the template type argument or non-type template argument.
50
    /// \param Loc the location of the type.
51
    ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
52
208k
      : Kind(Kind), Arg(Arg), Loc(Loc) { }
53
    
54
    /// \brief Create a template template argument.
55
    ///
56
    /// \param SS the C++ scope specifier that precedes the template name, if
57
    /// any.
58
    ///
59
    /// \param Template the template to which this template template 
60
    /// argument refers.
61
    ///
62
    /// \param TemplateLoc the location of the template name.
63
    ParsedTemplateArgument(const CXXScopeSpec &SS,
64
                           ParsedTemplateTy Template, 
65
                           SourceLocation TemplateLoc) 
66
      : Kind(ParsedTemplateArgument::Template),
67
        Arg(Template.getAsOpaquePtr()), 
68
746
        SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
69
    
70
    /// \brief Determine whether the given template argument is invalid.
71
257k
    bool isInvalid() const { return Arg == nullptr; }
72
    
73
    /// \brief Determine what kind of template argument we have.
74
206k
    KindType getKind() const { return Kind; }
75
    
76
    /// \brief Retrieve the template type argument's type.
77
161k
    ParsedType getAsType() const {
78
161k
      assert(Kind == Type && "Not a template type argument");
79
161k
      return ParsedType::getFromOpaquePtr(Arg);
80
161k
    }
81
    
82
    /// \brief Retrieve the non-type template argument's expression.
83
44.3k
    Expr *getAsExpr() const {
84
44.3k
      assert(Kind == NonType && "Not a non-type template argument");
85
44.3k
      return static_cast<Expr*>(Arg);
86
44.3k
    }
87
    
88
    /// \brief Retrieve the template template argument's template name.
89
764
    ParsedTemplateTy getAsTemplate() const {
90
764
      assert(Kind == Template && "Not a template template argument");
91
764
      return ParsedTemplateTy::getFromOpaquePtr(Arg);
92
764
    }
93
    
94
    /// \brief Retrieve the location of the template argument.
95
1.24k
    SourceLocation getLocation() const { return Loc; }
96
    
97
    /// \brief Retrieve the nested-name-specifier that precedes the template
98
    /// name in a template template argument.
99
745
    const CXXScopeSpec &getScopeSpec() const {
100
745
      assert(Kind == Template && 
101
745
             "Only template template arguments can have a scope specifier");
102
745
      return SS;
103
745
    }
104
    
105
    /// \brief Retrieve the location of the ellipsis that makes a template
106
    /// template argument into a pack expansion.
107
1.49k
    SourceLocation getEllipsisLoc() const {
108
1.49k
      assert(Kind == Template && 
109
1.49k
             "Only template template arguments can have an ellipsis");
110
1.49k
      return EllipsisLoc;
111
1.49k
    }
112
    
113
    /// \brief Retrieve a pack expansion of the given template template
114
    /// argument.
115
    ///
116
    /// \param EllipsisLoc The location of the ellipsis.
117
    ParsedTemplateArgument getTemplatePackExpansion(
118
                                              SourceLocation EllipsisLoc) const;
119
    
120
  private:
121
    KindType Kind;
122
    
123
    /// \brief The actual template argument representation, which may be
124
    /// an \c Sema::TypeTy* (for a type), an Expr* (for an
125
    /// expression), or an Sema::TemplateTy (for a template).
126
    void *Arg;
127
128
    /// \brief The nested-name-specifier that can accompany a template template
129
    /// argument.
130
    CXXScopeSpec SS;
131
132
    /// \brief the location of the template argument.
133
    SourceLocation Loc;
134
135
    /// \brief The ellipsis location that can accompany a template template
136
    /// argument (turning it into a template template argument expansion).
137
    SourceLocation EllipsisLoc;
138
  };
139
  
140
  /// \brief Information about a template-id annotation
141
  /// token.
142
  ///
143
  /// A template-id annotation token contains the template declaration, 
144
  /// template arguments, whether those template arguments were types, 
145
  /// expressions, or template names, and the source locations for important 
146
  /// tokens. All of the information about template arguments is allocated 
147
  /// directly after this structure.
148
  struct TemplateIdAnnotation final
149
      : private llvm::TrailingObjects<TemplateIdAnnotation,
150
                                      ParsedTemplateArgument> {
151
    friend TrailingObjects;
152
    /// \brief The nested-name-specifier that precedes the template name.
153
    CXXScopeSpec SS;
154
155
    /// TemplateKWLoc - The location of the template keyword.
156
    /// For e.g. typename T::template Y<U>
157
    SourceLocation TemplateKWLoc;
158
159
    /// TemplateNameLoc - The location of the template name within the
160
    /// source.
161
    SourceLocation TemplateNameLoc;
162
    
163
    /// FIXME: Temporarily stores the name of a specialization
164
    IdentifierInfo *Name;
165
    
166
    /// FIXME: Temporarily stores the overloaded operator kind.
167
    OverloadedOperatorKind Operator;
168
    
169
    /// The declaration of the template corresponding to the
170
    /// template-name.
171
    ParsedTemplateTy Template;
172
    
173
    /// The kind of template that Template refers to.
174
    TemplateNameKind Kind;
175
    
176
    /// The location of the '<' before the template argument
177
    /// list.
178
    SourceLocation LAngleLoc;
179
    
180
    /// The location of the '>' after the template argument
181
    /// list.
182
    SourceLocation RAngleLoc;
183
    
184
    /// NumArgs - The number of template arguments.
185
    unsigned NumArgs;
186
    
187
    /// \brief Retrieves a pointer to the template arguments
188
545k
    ParsedTemplateArgument *getTemplateArgs() { 
189
545k
      return getTrailingObjects<ParsedTemplateArgument>(); 
190
545k
    }
191
192
    /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
193
    /// appends it to List.
194
    static TemplateIdAnnotation *
195
    Create(CXXScopeSpec SS, SourceLocation TemplateKWLoc,
196
           SourceLocation TemplateNameLoc, IdentifierInfo *Name,
197
           OverloadedOperatorKind OperatorKind,
198
           ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
199
           SourceLocation LAngleLoc, SourceLocation RAngleLoc,
200
           ArrayRef<ParsedTemplateArgument> TemplateArgs,
201
134k
           SmallVectorImpl<TemplateIdAnnotation *> &CleanupList) {
202
134k
203
134k
      TemplateIdAnnotation *TemplateId = new (std::malloc(
204
134k
          totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
205
134k
          TemplateIdAnnotation(SS, TemplateKWLoc, TemplateNameLoc, Name,
206
134k
                               OperatorKind, OpaqueTemplateName, TemplateKind,
207
134k
                               LAngleLoc, RAngleLoc, TemplateArgs);
208
134k
      CleanupList.push_back(TemplateId);
209
134k
      return TemplateId;
210
134k
    }
211
212
134k
    void Destroy() {
213
134k
      std::for_each(
214
134k
          getTemplateArgs(), getTemplateArgs() + NumArgs,
215
205k
          [](ParsedTemplateArgument &A) { A.~ParsedTemplateArgument(); });
216
134k
      this->~TemplateIdAnnotation();
217
134k
      free(this); 
218
134k
    }
219
  private:
220
    TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;
221
222
    TemplateIdAnnotation(CXXScopeSpec SS, SourceLocation TemplateKWLoc,
223
                         SourceLocation TemplateNameLoc, IdentifierInfo *Name,
224
                         OverloadedOperatorKind OperatorKind,
225
                         ParsedTemplateTy OpaqueTemplateName,
226
                         TemplateNameKind TemplateKind,
227
                         SourceLocation LAngleLoc, SourceLocation RAngleLoc,
228
                         ArrayRef<ParsedTemplateArgument> TemplateArgs) noexcept
229
        : SS(SS), TemplateKWLoc(TemplateKWLoc),
230
          TemplateNameLoc(TemplateNameLoc), Name(Name), Operator(OperatorKind),
231
          Template(OpaqueTemplateName), Kind(TemplateKind),
232
          LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
233
134k
          NumArgs(TemplateArgs.size()) {
234
134k
235
134k
      std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(),
236
134k
                              getTemplateArgs());
237
134k
    }
238
134k
    ~TemplateIdAnnotation() = default;
239
  };
240
241
  /// Retrieves the range of the given template parameter lists.
242
  SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
243
                                     unsigned NumParams);  
244
} // end namespace clang
245
246
#endif // LLVM_CLANG_SEMA_PARSEDTEMPLATE_H