Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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
    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
      : 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()), SS(SS), Loc(TemplateLoc) {}
67
 
68
    /// Determine whether the given template argument is invalid.
69
    bool isInvalid() const { return Arg == nullptr; }
70
 
71
    /// Determine what kind of template argument we have.
72
    KindType getKind() const { return Kind; }
73
 
74
    /// Retrieve the template type argument's type.
75
    ParsedType getAsType() const {
76
      assert(Kind == Type && "Not a template type argument");
77
      return ParsedType::getFromOpaquePtr(Arg);
78
    }
79
 
80
    /// Retrieve the non-type template argument's expression.
81
    Expr *getAsExpr() const {
82
      assert(Kind == NonType && "Not a non-type template argument");
83
      return static_cast<Expr*>(Arg);
84
    }
85
 
86
    /// Retrieve the template template argument's template name.
87
    ParsedTemplateTy getAsTemplate() const {
88
      assert(Kind == Template && "Not a template template argument");
89
      return ParsedTemplateTy::getFromOpaquePtr(Arg);
90
    }
91
 
92
    /// Retrieve the location of the template argument.
93
    SourceLocation getLocation() const { return Loc; }
94
 
95
    /// Retrieve the nested-name-specifier that precedes the template
96
    /// name in a template template argument.
97
    const CXXScopeSpec &getScopeSpec() const {
98
      assert(Kind == Template &&
99
             "Only template template arguments can have a scope specifier");
100
      return SS;
101
    }
102
 
103
    /// Retrieve the location of the ellipsis that makes a template
104
    /// template argument into a pack expansion.
105
    SourceLocation getEllipsisLoc() const {
106
      assert(Kind == Template &&
107
             "Only template template arguments can have an ellipsis");
108
      return EllipsisLoc;
109
    }
110
 
111
    /// Retrieve a pack expansion of the given template template
112
    /// argument.
113
    ///
114
    /// \param EllipsisLoc The location of the ellipsis.
115
    ParsedTemplateArgument getTemplatePackExpansion(
116
                                              SourceLocation EllipsisLoc) const;
117
 
118
  private:
119
    KindType Kind;
120
 
121
    /// The actual template argument representation, which may be
122
    /// an \c Sema::TypeTy* (for a type), an Expr* (for an
123
    /// expression), or an Sema::TemplateTy (for a template).
124
    void *Arg;
125
 
126
    /// The nested-name-specifier that can accompany a template template
127
    /// argument.
128
    CXXScopeSpec SS;
129
 
130
    /// the location of the template argument.
131
    SourceLocation Loc;
132
 
133
    /// The ellipsis location that can accompany a template template
134
    /// argument (turning it into a template template argument expansion).
135
    SourceLocation EllipsisLoc;
136
  };
137
 
138
  /// Information about a template-id annotation
139
  /// token.
140
  ///
141
  /// A template-id annotation token contains the template name,
142
  /// template arguments, and the source locations for important
143
  /// tokens. All of the information about template arguments is allocated
144
  /// directly after this structure.
145
  /// A template-id annotation token can also be generated by a type-constraint
146
  /// construct with no explicit template arguments, e.g. "template<C T>" would
147
  /// annotate C as a TemplateIdAnnotation with no template arguments (the angle
148
  /// locations would be invalid in this case).
149
  struct TemplateIdAnnotation final
150
      : private llvm::TrailingObjects<TemplateIdAnnotation,
151
                                      ParsedTemplateArgument> {
152
    friend TrailingObjects;
153
    /// TemplateKWLoc - The location of the template keyword.
154
    /// For e.g. typename T::template Y<U>
155
    SourceLocation TemplateKWLoc;
156
 
157
    /// TemplateNameLoc - The location of the template name within the
158
    /// source.
159
    SourceLocation TemplateNameLoc;
160
 
161
    /// FIXME: Temporarily stores the name of a specialization
162
    IdentifierInfo *Name;
163
 
164
    /// FIXME: Temporarily stores the overloaded operator kind.
165
    OverloadedOperatorKind Operator;
166
 
167
    /// The declaration of the template corresponding to the
168
    /// template-name.
169
    ParsedTemplateTy Template;
170
 
171
    /// The kind of template that Template refers to. If this is
172
    /// TNK_Non_template, an error was encountered and diagnosed
173
    /// when parsing or looking up the template name.
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
    /// Whether an error was encountered in the template arguments.
188
    /// If so, NumArgs and the trailing arguments are best-effort.
189
    bool ArgsInvalid;
190
 
191
    /// Retrieves a pointer to the template arguments
192
    ParsedTemplateArgument *getTemplateArgs() {
193
      return getTrailingObjects<ParsedTemplateArgument>();
194
    }
195
 
196
    /// Creates a new TemplateIdAnnotation with NumArgs arguments and
197
    /// appends it to List.
198
    static TemplateIdAnnotation *
199
    Create(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc,
200
           IdentifierInfo *Name, OverloadedOperatorKind OperatorKind,
201
           ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
202
           SourceLocation LAngleLoc, SourceLocation RAngleLoc,
203
           ArrayRef<ParsedTemplateArgument> TemplateArgs, bool ArgsInvalid,
204
           SmallVectorImpl<TemplateIdAnnotation *> &CleanupList) {
205
      TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc(
206
          totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
207
          TemplateIdAnnotation(TemplateKWLoc, TemplateNameLoc, Name,
208
                               OperatorKind, OpaqueTemplateName, TemplateKind,
209
                               LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid);
210
      CleanupList.push_back(TemplateId);
211
      return TemplateId;
212
    }
213
 
214
    void Destroy() {
215
      for (ParsedTemplateArgument &A :
216
           llvm::make_range(getTemplateArgs(), getTemplateArgs() + NumArgs))
217
        A.~ParsedTemplateArgument();
218
      this->~TemplateIdAnnotation();
219
      free(this);
220
    }
221
 
222
    /// Determine whether this might be a type template.
223
    bool mightBeType() const {
224
      return Kind == TNK_Non_template ||
225
             Kind == TNK_Type_template ||
226
             Kind == TNK_Dependent_template_name ||
227
             Kind == TNK_Undeclared_template;
228
    }
229
 
230
    bool hasInvalidName() const { return Kind == TNK_Non_template; }
231
    bool hasInvalidArgs() const { return ArgsInvalid; }
232
 
233
    bool isInvalid() const { return hasInvalidName() || hasInvalidArgs(); }
234
 
235
  private:
236
    TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;
237
 
238
    TemplateIdAnnotation(SourceLocation TemplateKWLoc,
239
                         SourceLocation TemplateNameLoc, IdentifierInfo *Name,
240
                         OverloadedOperatorKind OperatorKind,
241
                         ParsedTemplateTy OpaqueTemplateName,
242
                         TemplateNameKind TemplateKind,
243
                         SourceLocation LAngleLoc, SourceLocation RAngleLoc,
244
                         ArrayRef<ParsedTemplateArgument> TemplateArgs,
245
                         bool ArgsInvalid) noexcept
246
        : TemplateKWLoc(TemplateKWLoc), TemplateNameLoc(TemplateNameLoc),
247
          Name(Name), Operator(OperatorKind), Template(OpaqueTemplateName),
248
          Kind(TemplateKind), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
249
          NumArgs(TemplateArgs.size()), ArgsInvalid(ArgsInvalid) {
250
 
251
      std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(),
252
                              getTemplateArgs());
253
    }
254
    ~TemplateIdAnnotation() = default;
255
  };
256
 
257
  /// Retrieves the range of the given template parameter lists.
258
  SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
259
                                     unsigned NumParams);
260
} // end namespace clang
261
 
262
#endif // LLVM_CLANG_SEMA_PARSEDTEMPLATE_H