Coverage Report

Created: 2018-07-20 23:04

/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
//                     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
  /// Represents the parsed form of a C++ template argument.
30
  class ParsedTemplateArgument {
31
  public:
32
    /// Describes the kind of template argument that was parsed.
33
    enum KindType {
34
      /// A template type parameter, stored as a type.
35
      Type,
36
      /// A non-type template parameter, stored as an expression.
37
      NonType,
38
      /// A template template argument, stored as a template name.
39
      Template
40
    };
41
42
    /// Build an empty template argument. 
43
    ///
44
    /// This template argument is invalid.
45
643k
    ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
46
    
47
    /// 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
4.01M
      : Kind(Kind), Arg(Arg), Loc(Loc) { }
53
    
54
    /// 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
2.04k
        SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
69
    
70
    /// Determine whether the given template argument is invalid.
71
4.66M
    bool isInvalid() const { return Arg == nullptr; }
72
    
73
    /// Determine what kind of template argument we have.
74
4.10M
    KindType getKind() const { return Kind; }
75
    
76
    /// Retrieve the template type argument's type.
77
3.35M
    ParsedType getAsType() const {
78
3.35M
      assert(Kind == Type && "Not a template type argument");
79
3.35M
      return ParsedType::getFromOpaquePtr(Arg);
80
3.35M
    }
81
    
82
    /// Retrieve the non-type template argument's expression.
83
652k
    Expr *getAsExpr() const {
84
652k
      assert(Kind == NonType && "Not a non-type template argument");
85
652k
      return static_cast<Expr*>(Arg);
86
652k
    }
87
    
88
    /// Retrieve the template template argument's template name.
89
2.07k
    ParsedTemplateTy getAsTemplate() const {
90
2.07k
      assert(Kind == Template && "Not a template template argument");
91
2.07k
      return ParsedTemplateTy::getFromOpaquePtr(Arg);
92
2.07k
    }
93
    
94
    /// Retrieve the location of the template argument.
95
89.2k
    SourceLocation getLocation() const { return Loc; }
96
    
97
    /// Retrieve the nested-name-specifier that precedes the template
98
    /// name in a template template argument.
99
2.04k
    const CXXScopeSpec &getScopeSpec() const {
100
2.04k
      assert(Kind == Template && 
101
2.04k
             "Only template template arguments can have a scope specifier");
102
2.04k
      return SS;
103
2.04k
    }
104
    
105
    /// Retrieve the location of the ellipsis that makes a template
106
    /// template argument into a pack expansion.
107
4.09k
    SourceLocation getEllipsisLoc() const {
108
4.09k
      assert(Kind == Template && 
109
4.09k
             "Only template template arguments can have an ellipsis");
110
4.09k
      return EllipsisLoc;
111
4.09k
    }
112
    
113
    /// 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
    /// 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
    /// The nested-name-specifier that can accompany a template template
129
    /// argument.
130
    CXXScopeSpec SS;
131
132
    /// the location of the template argument.
133
    SourceLocation Loc;
134
135
    /// 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
  /// 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
    /// 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
    /// Retrieves a pointer to the template arguments
188
9.98M
    ParsedTemplateArgument *getTemplateArgs() { 
189
9.98M
      return getTrailingObjects<ParsedTemplateArgument>(); 
190
9.98M
    }
191
192
    /// 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
2.44M
           SmallVectorImpl<TemplateIdAnnotation *> &CleanupList) {
202
2.44M
      TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc(
203
2.44M
          totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
204
2.44M
          TemplateIdAnnotation(SS, TemplateKWLoc, TemplateNameLoc, Name,
205
2.44M
                               OperatorKind, OpaqueTemplateName, TemplateKind,
206
2.44M
                               LAngleLoc, RAngleLoc, TemplateArgs);
207
2.44M
      CleanupList.push_back(TemplateId);
208
2.44M
      return TemplateId;
209
2.44M
    }
210
211
2.44M
    void Destroy() {
212
2.44M
      std::for_each(
213
2.44M
          getTemplateArgs(), getTemplateArgs() + NumArgs,
214
3.92M
          [](ParsedTemplateArgument &A) { A.~ParsedTemplateArgument(); });
215
2.44M
      this->~TemplateIdAnnotation();
216
2.44M
      free(this); 
217
2.44M
    }
218
  private:
219
    TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;
220
221
    TemplateIdAnnotation(CXXScopeSpec SS, SourceLocation TemplateKWLoc,
222
                         SourceLocation TemplateNameLoc, IdentifierInfo *Name,
223
                         OverloadedOperatorKind OperatorKind,
224
                         ParsedTemplateTy OpaqueTemplateName,
225
                         TemplateNameKind TemplateKind,
226
                         SourceLocation LAngleLoc, SourceLocation RAngleLoc,
227
                         ArrayRef<ParsedTemplateArgument> TemplateArgs) noexcept
228
        : SS(SS), TemplateKWLoc(TemplateKWLoc),
229
          TemplateNameLoc(TemplateNameLoc), Name(Name), Operator(OperatorKind),
230
          Template(OpaqueTemplateName), Kind(TemplateKind),
231
          LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
232
2.44M
          NumArgs(TemplateArgs.size()) {
233
2.44M
234
2.44M
      std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(),
235
2.44M
                              getTemplateArgs());
236
2.44M
    }
237
2.44M
    ~TemplateIdAnnotation() = default;
238
  };
239
240
  /// Retrieves the range of the given template parameter lists.
241
  SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
242
                                     unsigned NumParams);  
243
} // end namespace clang
244
245
#endif // LLVM_CLANG_SEMA_PARSEDTEMPLATE_H