Coverage Report

Created: 2019-07-24 05:18

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