MLIR  20.0.0git
Class.h
Go to the documentation of this file.
1 //===- Class.h - Helper classes for C++ code emission -----------*- 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 defines several classes for C++ code emission. They are only
10 // expected to be used by MLIR TableGen backends.
11 //
12 // We emit the declarations and definitions into separate files: *.h.inc and
13 // *.cpp.inc. The former is to be included in the dialect *.h and the latter for
14 // dialect *.cpp. This way provides a cleaner interface.
15 //
16 // In order to do this split, we need to track method signature and
17 // implementation logic separately. Signature information is used for both
18 // declaration and definition, while implementation logic is only for
19 // definition. So we have the following classes for C++ code emission.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 #ifndef MLIR_TABLEGEN_CLASS_H_
24 #define MLIR_TABLEGEN_CLASS_H_
25 
27 #include "mlir/Support/LLVM.h"
29 #include "llvm/ADT/SetVector.h"
30 #include "llvm/ADT/SmallVector.h"
31 #include "llvm/ADT/StringRef.h"
32 #include "llvm/ADT/StringSet.h"
33 #include "llvm/ADT/Twine.h"
34 
35 #include <set>
36 #include <string>
37 
38 namespace mlir {
39 namespace tblgen {
40 class FmtObjectBase;
41 
42 /// This class contains a single method parameter for a C++ function.
44 public:
45  /// Create a method parameter with a C++ type, parameter name, and an optional
46  /// default value. Marking a parameter as "optional" is a cosmetic effect on
47  /// the generated code.
48  template <typename TypeT, typename NameT, typename DefaultT>
49  MethodParameter(TypeT &&type, NameT &&name, DefaultT &&defaultValue,
50  bool optional = false)
51  : type(stringify(std::forward<TypeT>(type))),
52  name(stringify(std::forward<NameT>(name))),
53  defaultValue(stringify(std::forward<DefaultT>(defaultValue))),
54  optional(optional) {}
55 
56  /// Create a method parameter with a C++ type, parameter name, and no default
57  /// value.
58  template <typename TypeT, typename NameT>
59  MethodParameter(TypeT &&type, NameT &&name, bool optional = false)
60  : MethodParameter(std::forward<TypeT>(type), std::forward<NameT>(name),
61  /*defaultValue=*/"", optional) {}
62 
63  /// Write the parameter as part of a method declaration.
64  void writeDeclTo(raw_indented_ostream &os) const;
65  /// Write the parameter as part of a method definition.
66  void writeDefTo(raw_indented_ostream &os) const;
67 
68  /// Get the C++ type.
69  StringRef getType() const { return type; }
70  /// Get the C++ parameter name.
71  StringRef getName() const { return name; }
72  /// Returns true if the parameter has a default value.
73  bool hasDefaultValue() const { return !defaultValue.empty(); }
74 
75 private:
76  /// The C++ type.
77  std::string type;
78  /// The variable name.
79  std::string name;
80  /// An optional default value. The default value exists if the string is not
81  /// empty.
82  std::string defaultValue;
83  /// Whether the parameter should be indicated as "optional".
84  bool optional;
85 };
86 
87 /// This class contains a list of method parameters for constructor, class
88 /// methods, and method signatures.
90 public:
91  /// Create a list of method parameters.
92  MethodParameters(std::initializer_list<MethodParameter> parameters)
93  : parameters(parameters) {}
95  : parameters(std::move(parameters)) {}
96 
97  /// Write the parameters as part of a method declaration.
98  void writeDeclTo(raw_indented_ostream &os) const;
99  /// Write the parameters as part of a method definition.
100  void writeDefTo(raw_indented_ostream &os) const;
101 
102  /// Determine whether this list of parameters "subsumes" another, which occurs
103  /// when this parameter list is identical to the other and has zero or more
104  /// additional default-valued parameters.
105  bool subsumes(const MethodParameters &other) const;
106 
107  /// Return the number of parameters.
108  unsigned getNumParameters() const { return parameters.size(); }
109 
110 private:
111  /// The list of parameters.
112  SmallVector<MethodParameter> parameters;
113 };
114 
115 /// This class contains the signature of a C++ method, including the return
116 /// type. method name, and method parameters.
118 public:
119  /// Create a method signature with a return type, a method name, and a list of
120  /// parameters. Take ownership of the list.
121  template <typename RetTypeT, typename NameT>
122  MethodSignature(RetTypeT &&retType, NameT &&name,
123  SmallVector<MethodParameter> &&parameters)
124  : returnType(stringify(std::forward<RetTypeT>(retType))),
125  methodName(stringify(std::forward<NameT>(name))),
126  parameters(std::move(parameters)) {}
127  /// Create a method signature with a return type, a method name, and a list of
128  /// parameters.
129  template <typename RetTypeT, typename NameT>
130  MethodSignature(RetTypeT &&retType, NameT &&name,
131  ArrayRef<MethodParameter> parameters)
132  : MethodSignature(std::forward<RetTypeT>(retType),
133  std::forward<NameT>(name),
134  SmallVector<MethodParameter>(parameters)) {}
135  /// Create a method signature with a return type, a method name, and a
136  /// variadic list of parameters.
137  template <typename RetTypeT, typename NameT, typename... Parameters>
138  MethodSignature(RetTypeT &&retType, NameT &&name, Parameters &&...parameters)
139  : MethodSignature(std::forward<RetTypeT>(retType),
140  std::forward<NameT>(name),
142  {std::forward<Parameters>(parameters)...})) {}
143 
144  /// Determine whether a method with this signature makes a method with
145  /// `other` signature redundant. This occurs if the signatures have the same
146  /// name and this signature's parameteres subsume the other's.
147  ///
148  /// A method that makes another method redundant with a different return type
149  /// can replace the other, the assumption being that the subsuming method
150  /// provides a more resolved return type, e.g. IntegerAttr vs. Attribute.
151  bool makesRedundant(const MethodSignature &other) const;
152 
153  /// Get the name of the method.
154  StringRef getName() const { return methodName; }
155 
156  /// Get the return type of the method
157  StringRef getReturnType() const { return returnType; }
158 
159  /// Get the number of parameters.
160  unsigned getNumParameters() const { return parameters.getNumParameters(); }
161 
162  /// Write the signature as part of a method declaration.
163  void writeDeclTo(raw_indented_ostream &os) const;
164 
165  /// Write the signature as part of a method definition. `namePrefix` is to be
166  /// prepended to the method name (typically namespaces for qualifying the
167  /// method definition).
168  void writeDefTo(raw_indented_ostream &os, StringRef namePrefix) const;
169 
170  /// Write the template parameters of the signature.
172 
173  /// Add a template parameter.
174  template <typename ParamT>
175  void addTemplateParam(ParamT param) {
176  templateParams.push_back(stringify(param));
177  }
178 
179  /// Add a list of template parameters.
180  template <typename ContainerT>
181  void addTemplateParams(ContainerT &&container) {
182  templateParams.insert(std::begin(container), std::end(container));
183  }
184 
185 private:
186  /// The method's C++ return type.
187  std::string returnType;
188  /// The method name.
189  std::string methodName;
190  /// The method's parameter list.
191  MethodParameters parameters;
192  /// An optional list of template parameters.
193  SmallVector<std::string, 0> templateParams;
194 };
195 
196 /// This class contains the body of a C++ method.
197 class MethodBody {
198 public:
199  /// Create a method body, indicating whether it should be elided for methods
200  /// that are declaration-only.
201  MethodBody(bool declOnly);
202 
203  /// Define a move constructor to correctly initialize the streams.
205  : declOnly(other.declOnly), body(std::move(other.body)), stringOs(body),
206  os(stringOs) {}
207  /// Define a move assignment operator. `raw_ostream` has deleted assignment
208  /// operators, so reinitialize the whole object.
210  this->~MethodBody();
211  new (this) MethodBody(std::move(body));
212  return *this;
213  }
214 
215  /// Write a value to the method body.
216  template <typename ValueT>
217  MethodBody &operator<<(ValueT &&value) {
218  if (!declOnly) {
219  os << std::forward<ValueT>(value);
220  os.flush();
221  }
222  return *this;
223  }
224 
225  /// Write the method body to the output stream. The body can be written as
226  /// part of the declaration of an inline method or just in the definition.
227  void writeTo(raw_indented_ostream &os) const;
228 
229  /// Indent the output stream.
231  os.indent();
232  return *this;
233  }
234  /// Unindent the output stream.
236  os.unindent();
237  return *this;
238  }
239  /// Create a delimited scope: immediately print `open`, indent if `indent` is
240  /// true, and print `close` on object destruction.
242  scope(StringRef open = "", StringRef close = "", bool indent = false) {
243  return os.scope(open, close, indent);
244  }
245 
246  /// Get the underlying indented output stream.
247  raw_indented_ostream &getStream() { return os; }
248 
249 private:
250  /// Whether the body should be elided.
251  bool declOnly;
252  /// The body data.
253  std::string body;
254  /// The string output stream.
255  llvm::raw_string_ostream stringOs;
256  /// An indented output stream for formatting input.
258 };
259 
260 /// A class declaration is a class element that appears as part of its
261 /// declaration.
263 public:
264  virtual ~ClassDeclaration() = default;
265 
266  /// Kinds for LLVM-style RTTI.
267  enum Kind {
273  };
274  /// Create a class declaration with a given kind.
275  ClassDeclaration(Kind kind) : kind(kind) {}
276 
277  /// Get the class declaration kind.
278  Kind getKind() const { return kind; }
279 
280  /// Write the declaration.
281  virtual void writeDeclTo(raw_indented_ostream &os) const = 0;
282 
283  /// Write the definition, if any. `namePrefix` is the namespace prefix, which
284  /// may contains a class name.
286  StringRef namePrefix) const {}
287 
288 private:
289  /// The class declaration kind.
290  Kind kind;
291 };
292 
293 /// Base class for class declarations.
294 template <ClassDeclaration::Kind DeclKind>
296 public:
299 
300  static bool classof(const ClassDeclaration *other) {
301  return other->getKind() == DeclKind;
302  }
303 };
304 
305 /// Class for holding an op's method for C++ code emission
306 class Method : public ClassDeclarationBase<ClassDeclaration::Method> {
307 public:
308  /// Properties (qualifiers) of class methods. Bitfield is used here to help
309  /// querying properties.
310  enum Properties {
311  None = 0x0,
312  Static = 0x1,
313  Constructor = 0x2,
314  Private = 0x4,
315  Declaration = 0x8,
316  Inline = 0x10,
318  Const = 0x40,
319 
325  };
326 
327  /// Create a method with a return type, a name, method properties, and a some
328  /// parameters. The parameteres may be passed as a list or as a variadic pack.
329  template <typename RetTypeT, typename NameT, typename... Args>
330  Method(RetTypeT &&retType, NameT &&name, Properties properties,
331  Args &&...args)
333  methodSignature(std::forward<RetTypeT>(retType),
334  std::forward<NameT>(name), std::forward<Args>(args)...),
336  /// Create a method with a return type, a name, method properties, and a list
337  /// of parameters.
338  Method(StringRef retType, StringRef name, Properties properties,
339  std::initializer_list<MethodParameter> params)
340  : properties(properties), methodSignature(retType, name, params),
342 
343  // Define move constructor and assignment operator to prevent copying.
344  Method(Method &&) = default;
345  Method &operator=(Method &&) = default;
346 
347  /// Get the method body.
348  MethodBody &body() { return methodBody; }
349 
350  /// Sets or removes the deprecation message of the method.
351  void setDeprecated(std::optional<StringRef> message) {
352  this->deprecationMessage = message;
353  }
354 
355  /// Returns true if this is a static method.
356  bool isStatic() const { return properties & Static; }
357 
358  /// Returns true if this is a private method.
359  bool isPrivate() const { return properties & Private; }
360 
361  /// Returns true if this is an inline method.
362  bool isInline() const { return properties & Inline; }
363 
364  /// Returns true if this is a constructor.
365  bool isConstructor() const { return properties & Constructor; }
366 
367  /// Returns true if this class method is const.
368  bool isConst() const { return properties & Const; }
369 
370  /// Returns the name of this method.
371  StringRef getName() const { return methodSignature.getName(); }
372 
373  /// Returns the return type of this method
374  StringRef getReturnType() const { return methodSignature.getReturnType(); }
375 
376  /// Returns if this method makes the `other` method redundant.
377  bool makesRedundant(const Method &other) const {
379  }
380 
381  /// Write the method declaration, including the definition if inline.
382  void writeDeclTo(raw_indented_ostream &os) const override;
383 
384  /// Write the method definition. This is a no-op for inline methods.
386  StringRef namePrefix) const override;
387 
388  /// Add a template parameter.
389  template <typename ParamT>
390  void addTemplateParam(ParamT param);
391 
392  /// Add a list of template parameters.
393  template <typename ContainerT>
394  void addTemplateParams(ContainerT &&container);
395 
396 protected:
397  /// A collection of method properties.
399  /// The signature of the method.
401  /// The body of the method, if it has one.
403  /// Deprecation message if the method is deprecated.
404  std::optional<std::string> deprecationMessage;
405 };
406 
407 /// This enum describes C++ inheritance visibility.
409 
410 /// Write "public", "protected", or "private".
411 llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
412  mlir::tblgen::Visibility visibility);
413 
414 // Class for holding an op's constructor method for C++ code emission.
415 class Constructor : public Method {
416 public:
417  /// Create a constructor for a given class, with method properties, and
418  /// parameters specified either as a list of a variadic pack.
419  template <typename NameT, typename... Args>
420  Constructor(NameT &&className, Properties properties, Args &&...args)
421  : Method("", std::forward<NameT>(className), properties,
422  std::forward<Args>(args)...) {}
423 
424  /// Add member initializer to constructor initializing `name` with `value`.
425  template <typename NameT, typename ValueT>
426  void addMemberInitializer(NameT &&name, ValueT &&value) {
427  initializers.emplace_back(stringify(std::forward<NameT>(name)),
428  stringify(std::forward<ValueT>(value)));
429  }
430 
431  /// Write the declaration of the constructor, and its definition if inline.
432  void writeDeclTo(raw_indented_ostream &os) const override;
433 
434  /// Write the definition of the constructor if it is not inline.
436  StringRef namePrefix) const override;
437 
438  /// Return true if a method is a constructor.
439  static bool classof(const ClassDeclaration *other) {
440  return isa<Method>(other) && cast<Method>(other)->isConstructor();
441  }
442 
443  /// Initialization of a class field in a constructor.
445  public:
446  /// Create a member initializer in a constructor that initializes the class
447  /// field `name` with `value`.
448  MemberInitializer(std::string name, std::string value)
449  : name(std::move(name)), value(std::move(value)) {}
450 
451  /// Write the member initializer.
452  void writeTo(raw_indented_ostream &os) const;
453 
454  private:
455  /// The name of the class field.
456  std::string name;
457  /// The value with which to initialize it.
458  std::string value;
459  };
460 
461 private:
462  /// The list of member initializers.
463  SmallVector<MemberInitializer> initializers;
464 };
465 
466 } // namespace tblgen
467 } // namespace mlir
468 
469 /// The OR of two method properties should return method properties. Ensure that
470 /// this function is visible to `Class`.
471 inline constexpr mlir::tblgen::Method::Properties
474  return mlir::tblgen::Method::Properties(static_cast<unsigned>(lhs) |
475  static_cast<unsigned>(rhs));
476 }
477 
478 inline constexpr mlir::tblgen::Method::Properties &
481  return lhs = mlir::tblgen::Method::Properties(static_cast<unsigned>(lhs) |
482  static_cast<unsigned>(rhs));
483 }
484 
485 namespace mlir {
486 namespace tblgen {
487 
488 template <typename ParamT>
489 void Method::addTemplateParam(ParamT param) {
490  // Templates imply inline.
493 }
494 
495 template <typename ContainerT>
496 void Method::addTemplateParams(ContainerT &&container) {
497  // Templates imply inline.
499  methodSignature.addTemplateParam(std::forward<ContainerT>(container));
500 }
501 
502 /// This class describes a C++ parent class declaration.
503 class ParentClass {
504 public:
505  /// Create a parent class with a class name and visibility.
506  template <typename NameT>
507  ParentClass(NameT &&name, Visibility visibility = Visibility::Public)
508  : name(stringify(std::forward<NameT>(name))), visibility(visibility) {}
509 
510  /// Add a template parameter.
511  template <typename ParamT>
512  void addTemplateParam(ParamT param) {
513  templateParams.insert(stringify(param));
514  }
515  /// Add a list of template parameters.
516  template <typename ContainerT>
517  void addTemplateParams(ContainerT &&container) {
518  templateParams.insert(std::begin(container), std::end(container));
519  }
520 
521  /// Write the parent class declaration.
522  void writeTo(raw_indented_ostream &os) const;
523 
524 private:
525  /// The fully resolved C++ name of the parent class.
526  std::string name;
527  /// The visibility of the parent class.
528  Visibility visibility;
529  /// An optional list of class template parameters.
531 };
532 
533 /// This class describes a using-declaration for a class. E.g.
534 ///
535 /// using Op::Op;
536 /// using Adaptor = OpAdaptor;
537 ///
539  : public ClassDeclarationBase<ClassDeclaration::UsingDeclaration> {
540 public:
541  /// Create a using declaration that either aliases `name` to `value` or
542  /// inherits the parent methods `name.
543  template <typename NameT, typename ValueT = std::string>
544  UsingDeclaration(NameT &&name, ValueT &&value = "")
545  : name(stringify(std::forward<NameT>(name))),
546  value(stringify(std::forward<ValueT>(value))) {}
547 
548  /// Write the using declaration.
549  void writeDeclTo(raw_indented_ostream &os) const override;
550 
551  /// Add a template parameter.
552  template <typename ParamT>
553  void addTemplateParam(ParamT param) {
554  templateParams.insert(stringify(param));
555  }
556 
557  /// Add a list of template parameters.
558  template <typename ContainerT>
559  void addTemplateParams(ContainerT &&container) {
560  templateParams.insert(std::begin(container), std::end(container));
561  }
562 
563 private:
564  /// The name of the declaration, or a resolved name to an inherited function.
565  std::string name;
566  /// The type that is being aliased. Leave empty for inheriting functions.
567  std::string value;
568  /// An optional list of class template parameters.
569  /// This is simply a ordered list of parameter names that are then added as
570  /// template type parameters when the using declaration is emitted.
572 };
573 
574 /// This class describes a class field.
575 class Field : public ClassDeclarationBase<ClassDeclaration::Field> {
576 public:
577  /// Create a class field with a type and variable name.
578  template <typename TypeT, typename NameT>
579  Field(TypeT &&type, NameT &&name)
580  : type(stringify(std::forward<TypeT>(type))),
581  name(stringify(std::forward<NameT>(name))) {}
582 
583  /// Write the declaration of the field.
584  void writeDeclTo(raw_indented_ostream &os) const override;
585 
586 private:
587  /// The C++ type of the field.
588  std::string type;
589  /// The variable name of the class whether.
590  std::string name;
591 };
592 
593 /// A declaration for the visibility of subsequent declarations.
595  : public ClassDeclarationBase<ClassDeclaration::VisibilityDeclaration> {
596 public:
597  /// Create a declaration for the given visibility.
598  VisibilityDeclaration(Visibility visibility) : visibility(visibility) {}
599 
600  /// Get the visibility.
601  Visibility getVisibility() const { return visibility; }
602 
603  /// Write the visibility declaration.
604  void writeDeclTo(raw_indented_ostream &os) const override;
605 
606 private:
607  /// The visibility of subsequent class declarations.
608  Visibility visibility;
609 };
610 
611 /// Unstructured extra class declarations and definitions, from TableGen
612 /// definitions. The default visibility of extra class declarations is up to the
613 /// owning class.
615  : public ClassDeclarationBase<ClassDeclaration::ExtraClassDeclaration> {
616 public:
617  /// Create an extra class declaration.
618  ExtraClassDeclaration(StringRef extraClassDeclaration,
619  std::string extraClassDefinition = "")
620  : ExtraClassDeclaration(extraClassDeclaration.str(),
621  std::move(extraClassDefinition)) {}
622 
623  ExtraClassDeclaration(std::string extraClassDeclaration,
624  std::string extraClassDefinition = "")
625  : extraClassDeclaration(extraClassDeclaration),
626  extraClassDefinition(extraClassDefinition) {}
627 
628  /// Write the extra class declarations.
629  void writeDeclTo(raw_indented_ostream &os) const override;
630 
631  /// Write the extra class definitions.
633  StringRef namePrefix) const override;
634 
635 private:
636  /// The string of the extra class declarations. It is re-indented before
637  /// printed.
638  std::string extraClassDeclaration;
639  /// The string of the extra class definitions. It is re-indented before
640  /// printed.
641  std::string extraClassDefinition;
642 };
643 
644 /// A class used to emit C++ classes from Tablegen. Contains a list of public
645 /// methods and a list of private fields to be emitted.
646 class Class {
647 public:
648  virtual ~Class() = default;
649 
650  /// Explicitly delete the copy constructor. This is to work around a gcc-5 bug
651  /// with std::is_trivially_move_constructible.
652  Class(const Class &) = delete;
653 
654  /// Create a class with a name, and whether it should be declared as a `class`
655  /// or `struct`. Also, prevent this from being mistaken as a move constructor
656  /// candidate.
657  template <typename NameT,
658  typename = std::enable_if_t<!std::is_same<NameT, Class>::value>>
659  Class(NameT &&name, bool isStruct = false)
660  : className(stringify(std::forward<NameT>(name))), isStruct(isStruct) {}
661 
662  /// Add a new constructor to this class and prune and constructors made
663  /// redundant by it. Returns null if the constructor was not added. Else,
664  /// returns a pointer to the new constructor.
665  template <Method::Properties Properties = Method::None, typename... Args>
666  Constructor *addConstructor(Args &&...args) {
667  Method::Properties defaultProperties = Method::Constructor;
668  // If the class has template parameters, the constructor has to be defined
669  // inline.
670  if (!templateParams.empty())
671  defaultProperties |= Method::Inline;
673  Properties | defaultProperties,
674  std::forward<Args>(args)...));
675  }
676 
677  /// Add a new method to this class and prune any methods made redundant by it.
678  /// Returns null if the method was not added (because an existing method would
679  /// make it redundant). Else, returns a pointer to the new method.
680  template <Method::Properties Properties = Method::None, typename RetTypeT,
681  typename NameT>
682  Method *addMethod(RetTypeT &&retType, NameT &&name,
683  Method::Properties properties,
684  ArrayRef<MethodParameter> parameters) {
685  // If the class has template parameters, then it has to be defined inline.
686  if (!templateParams.empty())
687  properties |= Method::Inline;
688  return addMethodAndPrune(Method(std::forward<RetTypeT>(retType),
689  std::forward<NameT>(name),
690  Properties | properties, parameters));
691  }
692 
693  /// Add a method with statically-known properties.
694  template <Method::Properties Properties = Method::None, typename RetTypeT,
695  typename NameT>
696  Method *addMethod(RetTypeT &&retType, NameT &&name,
697  ArrayRef<MethodParameter> parameters) {
698  return addMethod(std::forward<RetTypeT>(retType), std::forward<NameT>(name),
699  Properties, parameters);
700  }
701 
702  template <Method::Properties Properties = Method::None, typename RetTypeT,
703  typename NameT, typename... Args>
704  Method *addMethod(RetTypeT &&retType, NameT &&name,
705  Method::Properties properties, Args &&...args) {
706  return addMethod(std::forward<RetTypeT>(retType), std::forward<NameT>(name),
707  properties | Properties, {std::forward<Args>(args)...});
708  }
709 
710  /// Add a method with statically-known properties.
711  template <Method::Properties Properties = Method::None, typename RetTypeT,
712  typename NameT, typename... Args>
713  Method *addMethod(RetTypeT &&retType, NameT &&name, Args &&...args) {
714  return addMethod(std::forward<RetTypeT>(retType), std::forward<NameT>(name),
715  Properties, std::forward<Args>(args)...);
716  }
717 
718  /// Add a static method.
719  template <Method::Properties Properties = Method::None, typename RetTypeT,
720  typename NameT, typename... Args>
721  Method *addStaticMethod(RetTypeT &&retType, NameT &&name, Args &&...args) {
722  return addMethod<Properties | Method::Static>(
723  std::forward<RetTypeT>(retType), std::forward<NameT>(name),
724  std::forward<Args>(args)...);
725  }
726 
727  /// Add an inline static method.
728  template <Method::Properties Properties = Method::None, typename RetTypeT,
729  typename NameT, typename... Args>
730  Method *addStaticInlineMethod(RetTypeT &&retType, NameT &&name,
731  Args &&...args) {
732  return addMethod<Properties | Method::StaticInline>(
733  std::forward<RetTypeT>(retType), std::forward<NameT>(name),
734  std::forward<Args>(args)...);
735  }
736 
737  /// Add an inline method.
738  template <Method::Properties Properties = Method::None, typename RetTypeT,
739  typename NameT, typename... Args>
740  Method *addInlineMethod(RetTypeT &&retType, NameT &&name, Args &&...args) {
741  return addMethod<Properties | Method::Inline>(
742  std::forward<RetTypeT>(retType), std::forward<NameT>(name),
743  std::forward<Args>(args)...);
744  }
745 
746  /// Add a const method.
747  template <Method::Properties Properties = Method::None, typename RetTypeT,
748  typename NameT, typename... Args>
749  Method *addConstMethod(RetTypeT &&retType, NameT &&name, Args &&...args) {
750  return addMethod<Properties | Method::Const>(
751  std::forward<RetTypeT>(retType), std::forward<NameT>(name),
752  std::forward<Args>(args)...);
753  }
754 
755  /// Add a declaration for a method.
756  template <Method::Properties Properties = Method::None, typename RetTypeT,
757  typename NameT, typename... Args>
758  Method *declareMethod(RetTypeT &&retType, NameT &&name, Args &&...args) {
759  return addMethod<Properties | Method::Declaration>(
760  std::forward<RetTypeT>(retType), std::forward<NameT>(name),
761  std::forward<Args>(args)...);
762  }
763 
764  /// Add a declaration for a static method.
765  template <Method::Properties Properties = Method::None, typename RetTypeT,
766  typename NameT, typename... Args>
767  Method *declareStaticMethod(RetTypeT &&retType, NameT &&name,
768  Args &&...args) {
769  return addMethod<Properties | Method::StaticDeclaration>(
770  std::forward<RetTypeT>(retType), std::forward<NameT>(name),
771  std::forward<Args>(args)...);
772  }
773 
774  /// Add a new field to the class. Class fields added this way are always
775  /// private.
776  template <typename TypeT, typename NameT>
777  void addField(TypeT &&type, NameT &&name) {
778  fields.emplace_back(std::forward<TypeT>(type), std::forward<NameT>(name));
779  }
780 
781  /// Add a parent class.
783 
784  /// Add a template parameter.
785  template <typename ParamT>
786  void addTemplateParam(ParamT param) {
787  templateParams.insert(stringify(param));
788  }
789 
790  /// Add a list of template parameters.
791  template <typename ContainerT>
792  void addTemplateParams(ContainerT &&container) {
793  templateParams.insert(std::begin(container), std::end(container));
794  }
795 
796  /// Return the C++ name of the class.
797  StringRef getClassName() const { return className; }
798 
799  /// Write the declaration of this class, all declarations, and definitions of
800  /// inline functions. Wrap the output stream in an indented stream.
801  void writeDeclTo(raw_ostream &rawOs) const {
802  raw_indented_ostream os(rawOs);
803  writeDeclTo(os);
804  }
805  /// Write the definitions of thiss class's out-of-line constructors and
806  /// methods. Wrap the output stream in an indented stream.
807  void writeDefTo(raw_ostream &rawOs) const {
808  raw_indented_ostream os(rawOs);
809  writeDefTo(os);
810  }
811 
812  /// Write the declaration of this class, all declarations, and definitions of
813  /// inline functions.
815  /// Write the definitions of thiss class's out-of-line constructors and
816  /// methods.
818 
819  /// Add a declaration. The declaration is appended directly to the list of
820  /// class declarations.
821  template <typename DeclT, typename... Args>
822  DeclT *declare(Args &&...args) {
823  auto decl = std::make_unique<DeclT>(std::forward<Args>(args)...);
824  auto *ret = decl.get();
825  declarations.push_back(std::move(decl));
826  return ret;
827  }
828 
829  /// The declaration of a class needs to be "finalized".
830  ///
831  /// Class constructors, methods, and fields can be added in any order,
832  /// regardless of whether they are public or private. These are stored in
833  /// lists separate from list of declarations `declarations`.
834  ///
835  /// So that the generated C++ code is somewhat organised, public methods are
836  /// declared together, and so are private methods and class fields. This
837  /// function iterates through all the added methods and fields and organises
838  /// them into the list of declarations, adding visibility declarations as
839  /// needed, as follows:
840  ///
841  /// 1. public methods and constructors
842  /// 2. private methods and constructors
843  /// 3. class fields -- all are private
844  ///
845  /// `Class::finalize` clears the lists of pending methods and fields, and can
846  /// be called multiple times.
847  virtual void finalize();
848 
849 protected:
850  /// Add a new constructor if it is not made redundant by any existing
851  /// constructors and prune and existing constructors made redundant.
853  /// Add a new method if it is not made redundant by any existing methods and
854  /// prune and existing methods made redundant.
856 
857  /// Get the last visibility declaration.
859 
860  /// The C++ class name.
861  std::string className;
862  /// The list of parent classes.
864  /// The pending list of methods and constructors.
865  std::vector<std::unique_ptr<Method>> methods;
866  /// The pending list of private class fields.
868  /// Whether this is a `class` or a `struct`.
869  bool isStruct;
870 
871  /// A list of declarations in the class, emitted in order.
872  std::vector<std::unique_ptr<ClassDeclaration>> declarations;
873 
874  /// An optional list of class template parameters.
876 };
877 
878 } // namespace tblgen
879 } // namespace mlir
880 
881 #endif // MLIR_TABLEGEN_CLASS_H_
constexpr mlir::tblgen::Method::Properties operator|(mlir::tblgen::Method::Properties lhs, mlir::tblgen::Method::Properties rhs)
The OR of two method properties should return method properties.
Definition: Class.h:472
constexpr mlir::tblgen::Method::Properties & operator|=(mlir::tblgen::Method::Properties &lhs, mlir::tblgen::Method::Properties rhs)
Definition: Class.h:479
raw_ostream subclass that simplifies indention a sequence of code.
raw_indented_ostream & unindent()
Decreases the indent and returning this raw_indented_ostream.
DelimitedScope scope(StringRef open="", StringRef close="", bool indent=true)
Returns DelimitedScope.
raw_indented_ostream & indent()
Increases the indent and returning this raw_indented_ostream.
Base class for class declarations.
Definition: Class.h:295
static bool classof(const ClassDeclaration *other)
Definition: Class.h:300
A class declaration is a class element that appears as part of its declaration.
Definition: Class.h:262
virtual ~ClassDeclaration()=default
ClassDeclaration(Kind kind)
Create a class declaration with a given kind.
Definition: Class.h:275
virtual void writeDeclTo(raw_indented_ostream &os) const =0
Write the declaration.
Kind getKind() const
Get the class declaration kind.
Definition: Class.h:278
Kind
Kinds for LLVM-style RTTI.
Definition: Class.h:267
virtual void writeDefTo(raw_indented_ostream &os, StringRef namePrefix) const
Write the definition, if any.
Definition: Class.h:285
A class used to emit C++ classes from Tablegen.
Definition: Class.h:646
Method * addInlineMethod(RetTypeT &&retType, NameT &&name, Args &&...args)
Add an inline method.
Definition: Class.h:740
virtual ~Class()=default
Class(const Class &)=delete
Explicitly delete the copy constructor.
Method * declareStaticMethod(RetTypeT &&retType, NameT &&name, Args &&...args)
Add a declaration for a static method.
Definition: Class.h:767
SetVector< std::string, SmallVector< std::string >, StringSet<> > templateParams
An optional list of class template parameters.
Definition: Class.h:875
Method * addMethod(RetTypeT &&retType, NameT &&name, Args &&...args)
Add a method with statically-known properties.
Definition: Class.h:713
std::vector< std::unique_ptr< ClassDeclaration > > declarations
A list of declarations in the class, emitted in order.
Definition: Class.h:872
DeclT * declare(Args &&...args)
Add a declaration.
Definition: Class.h:822
Method * declareMethod(RetTypeT &&retType, NameT &&name, Args &&...args)
Add a declaration for a method.
Definition: Class.h:758
ParentClass & addParent(ParentClass parent)
Add a parent class.
std::vector< std::unique_ptr< Method > > methods
The pending list of methods and constructors.
Definition: Class.h:865
void writeDeclTo(raw_indented_ostream &os) const
Write the declaration of this class, all declarations, and definitions of inline functions.
SmallVector< Field > fields
The pending list of private class fields.
Definition: Class.h:867
Method * addStaticInlineMethod(RetTypeT &&retType, NameT &&name, Args &&...args)
Add an inline static method.
Definition: Class.h:730
virtual void finalize()
The declaration of a class needs to be "finalized".
void writeDefTo(raw_ostream &rawOs) const
Write the definitions of thiss class's out-of-line constructors and methods.
Definition: Class.h:807
Constructor * addConstructorAndPrune(Constructor &&newCtor)
Add a new constructor if it is not made redundant by any existing constructors and prune and existing...
Visibility getLastVisibilityDecl() const
Get the last visibility declaration.
void addTemplateParam(ParamT param)
Add a template parameter.
Definition: Class.h:786
void addField(TypeT &&type, NameT &&name)
Add a new field to the class.
Definition: Class.h:777
Method * addMethod(RetTypeT &&retType, NameT &&name, Method::Properties properties, ArrayRef< MethodParameter > parameters)
Add a new method to this class and prune any methods made redundant by it.
Definition: Class.h:682
SmallVector< ParentClass > parents
The list of parent classes.
Definition: Class.h:863
Class(NameT &&name, bool isStruct=false)
Create a class with a name, and whether it should be declared as a class or struct.
Definition: Class.h:659
Method * addConstMethod(RetTypeT &&retType, NameT &&name, Args &&...args)
Add a const method.
Definition: Class.h:749
std::string className
The C++ class name.
Definition: Class.h:861
Constructor * addConstructor(Args &&...args)
Add a new constructor to this class and prune and constructors made redundant by it.
Definition: Class.h:666
bool isStruct
Whether this is a class or a struct.
Definition: Class.h:869
Method * addMethod(RetTypeT &&retType, NameT &&name, Method::Properties properties, Args &&...args)
Definition: Class.h:704
void writeDeclTo(raw_ostream &rawOs) const
Write the declaration of this class, all declarations, and definitions of inline functions.
Definition: Class.h:801
Method * addMethod(RetTypeT &&retType, NameT &&name, ArrayRef< MethodParameter > parameters)
Add a method with statically-known properties.
Definition: Class.h:696
Method * addStaticMethod(RetTypeT &&retType, NameT &&name, Args &&...args)
Add a static method.
Definition: Class.h:721
void writeDefTo(raw_indented_ostream &os) const
Write the definitions of thiss class's out-of-line constructors and methods.
Method * addMethodAndPrune(Method &&newMethod)
Add a new method if it is not made redundant by any existing methods and prune and existing methods m...
void addTemplateParams(ContainerT &&container)
Add a list of template parameters.
Definition: Class.h:792
StringRef getClassName() const
Return the C++ name of the class.
Definition: Class.h:797
Initialization of a class field in a constructor.
Definition: Class.h:444
void writeTo(raw_indented_ostream &os) const
Write the member initializer.
MemberInitializer(std::string name, std::string value)
Create a member initializer in a constructor that initializes the class field name with value.
Definition: Class.h:448
void addMemberInitializer(NameT &&name, ValueT &&value)
Add member initializer to constructor initializing name with value.
Definition: Class.h:426
void writeDefTo(raw_indented_ostream &os, StringRef namePrefix) const override
Write the definition of the constructor if it is not inline.
void writeDeclTo(raw_indented_ostream &os) const override
Write the declaration of the constructor, and its definition if inline.
Constructor(NameT &&className, Properties properties, Args &&...args)
Create a constructor for a given class, with method properties, and parameters specified either as a ...
Definition: Class.h:420
static bool classof(const ClassDeclaration *other)
Return true if a method is a constructor.
Definition: Class.h:439
Unstructured extra class declarations and definitions, from TableGen definitions.
Definition: Class.h:615
ExtraClassDeclaration(StringRef extraClassDeclaration, std::string extraClassDefinition="")
Create an extra class declaration.
Definition: Class.h:618
void writeDefTo(raw_indented_ostream &os, StringRef namePrefix) const override
Write the extra class definitions.
ExtraClassDeclaration(std::string extraClassDeclaration, std::string extraClassDefinition="")
Definition: Class.h:623
void writeDeclTo(raw_indented_ostream &os) const override
Write the extra class declarations.
This class describes a class field.
Definition: Class.h:575
void writeDeclTo(raw_indented_ostream &os) const override
Write the declaration of the field.
Field(TypeT &&type, NameT &&name)
Create a class field with a type and variable name.
Definition: Class.h:579
This class contains the body of a C++ method.
Definition: Class.h:197
void writeTo(raw_indented_ostream &os) const
Write the method body to the output stream.
Definition: Class.cpp:115
MethodBody & unindent()
Unindent the output stream.
Definition: Class.h:235
MethodBody(MethodBody &&other)
Define a move constructor to correctly initialize the streams.
Definition: Class.h:204
MethodBody & operator<<(ValueT &&value)
Write a value to the method body.
Definition: Class.h:217
MethodBody(bool declOnly)
Create a method body, indicating whether it should be elided for methods that are declaration-only.
Definition: Class.cpp:112
MethodBody & indent()
Indent the output stream.
Definition: Class.h:230
MethodBody & operator=(MethodBody &&body)
Define a move assignment operator.
Definition: Class.h:209
raw_indented_ostream & getStream()
Get the underlying indented output stream.
Definition: Class.h:247
raw_indented_ostream::DelimitedScope scope(StringRef open="", StringRef close="", bool indent=false)
Create a delimited scope: immediately print open, indent if indent is true, and print close on object...
Definition: Class.h:242
This class contains a single method parameter for a C++ function.
Definition: Class.h:43
StringRef getName() const
Get the C++ parameter name.
Definition: Class.h:71
void writeDefTo(raw_indented_ostream &os) const
Write the parameter as part of a method definition.
Definition: Class.cpp:37
bool hasDefaultValue() const
Returns true if the parameter has a default value.
Definition: Class.h:73
MethodParameter(TypeT &&type, NameT &&name, DefaultT &&defaultValue, bool optional=false)
Create a method parameter with a C++ type, parameter name, and an optional default value.
Definition: Class.h:49
void writeDeclTo(raw_indented_ostream &os) const
Write the parameter as part of a method declaration.
Definition: Class.cpp:29
MethodParameter(TypeT &&type, NameT &&name, bool optional=false)
Create a method parameter with a C++ type, parameter name, and no default value.
Definition: Class.h:59
StringRef getType() const
Get the C++ type.
Definition: Class.h:69
This class contains a list of method parameters for constructor, class methods, and method signatures...
Definition: Class.h:89
void writeDefTo(raw_indented_ostream &os) const
Write the parameters as part of a method definition.
Definition: Class.cpp:51
MethodParameters(SmallVector< MethodParameter > parameters)
Definition: Class.h:94
MethodParameters(std::initializer_list< MethodParameter > parameters)
Create a list of method parameters.
Definition: Class.h:92
bool subsumes(const MethodParameters &other) const
Determine whether this list of parameters "subsumes" another, which occurs when this parameter list i...
Definition: Class.cpp:56
unsigned getNumParameters() const
Return the number of parameters.
Definition: Class.h:108
void writeDeclTo(raw_indented_ostream &os) const
Write the parameters as part of a method declaration.
Definition: Class.cpp:47
This class contains the signature of a C++ method, including the return type.
Definition: Class.h:117
MethodSignature(RetTypeT &&retType, NameT &&name, SmallVector< MethodParameter > &&parameters)
Create a method signature with a return type, a method name, and a list of parameters.
Definition: Class.h:122
bool makesRedundant(const MethodSignature &other) const
Determine whether a method with this signature makes a method with other signature redundant.
Definition: Class.cpp:78
void writeDeclTo(raw_indented_ostream &os) const
Write the signature as part of a method declaration.
Definition: Class.cpp:83
MethodSignature(RetTypeT &&retType, NameT &&name, ArrayRef< MethodParameter > parameters)
Create a method signature with a return type, a method name, and a list of parameters.
Definition: Class.h:130
unsigned getNumParameters() const
Get the number of parameters.
Definition: Class.h:160
StringRef getName() const
Get the name of the method.
Definition: Class.h:154
void writeTemplateParamsTo(raw_indented_ostream &os) const
Write the template parameters of the signature.
Definition: Class.cpp:97
void addTemplateParam(ParamT param)
Add a template parameter.
Definition: Class.h:175
MethodSignature(RetTypeT &&retType, NameT &&name, Parameters &&...parameters)
Create a method signature with a return type, a method name, and a variadic list of parameters.
Definition: Class.h:138
void addTemplateParams(ContainerT &&container)
Add a list of template parameters.
Definition: Class.h:181
StringRef getReturnType() const
Get the return type of the method.
Definition: Class.h:157
void writeDefTo(raw_indented_ostream &os, StringRef namePrefix) const
Write the signature as part of a method definition.
Definition: Class.cpp:89
Class for holding an op's method for C++ code emission.
Definition: Class.h:306
void addTemplateParam(ParamT param)
Add a template parameter.
Definition: Class.h:489
Method(RetTypeT &&retType, NameT &&name, Properties properties, Args &&...args)
Create a method with a return type, a name, method properties, and a some parameters.
Definition: Class.h:330
bool isStatic() const
Returns true if this is a static method.
Definition: Class.h:356
MethodBody methodBody
The body of the method, if it has one.
Definition: Class.h:402
MethodSignature methodSignature
The signature of the method.
Definition: Class.h:400
bool makesRedundant(const Method &other) const
Returns if this method makes the other method redundant.
Definition: Class.h:377
Properties
Properties (qualifiers) of class methods.
Definition: Class.h:310
void writeDefTo(raw_indented_ostream &os, StringRef namePrefix) const override
Write the method definition. This is a no-op for inline methods.
void writeDeclTo(raw_indented_ostream &os) const override
Write the method declaration, including the definition if inline.
Definition: Class.cpp:128
Properties properties
A collection of method properties.
Definition: Class.h:398
std::optional< std::string > deprecationMessage
Deprecation message if the method is deprecated.
Definition: Class.h:404
MethodBody & body()
Get the method body.
Definition: Class.h:348
bool isPrivate() const
Returns true if this is a private method.
Definition: Class.h:359
StringRef getReturnType() const
Returns the return type of this method.
Definition: Class.h:374
void setDeprecated(std::optional< StringRef > message)
Sets or removes the deprecation message of the method.
Definition: Class.h:351
Method(Method &&)=default
bool isInline() const
Returns true if this is an inline method.
Definition: Class.h:362
StringRef getName() const
Returns the name of this method.
Definition: Class.h:371
Method(StringRef retType, StringRef name, Properties properties, std::initializer_list< MethodParameter > params)
Create a method with a return type, a name, method properties, and a list of parameters.
Definition: Class.h:338
bool isConstructor() const
Returns true if this is a constructor.
Definition: Class.h:365
void addTemplateParams(ContainerT &&container)
Add a list of template parameters.
Definition: Class.h:496
Method & operator=(Method &&)=default
bool isConst() const
Returns true if this class method is const.
Definition: Class.h:368
This class describes a C++ parent class declaration.
Definition: Class.h:503
void writeTo(raw_indented_ostream &os) const
Write the parent class declaration.
ParentClass(NameT &&name, Visibility visibility=Visibility::Public)
Create a parent class with a class name and visibility.
Definition: Class.h:507
void addTemplateParams(ContainerT &&container)
Add a list of template parameters.
Definition: Class.h:517
void addTemplateParam(ParamT param)
Add a template parameter.
Definition: Class.h:512
This class describes a using-declaration for a class.
Definition: Class.h:539
void writeDeclTo(raw_indented_ostream &os) const override
Write the using declaration.
void addTemplateParams(ContainerT &&container)
Add a list of template parameters.
Definition: Class.h:559
void addTemplateParam(ParamT param)
Add a template parameter.
Definition: Class.h:553
UsingDeclaration(NameT &&name, ValueT &&value="")
Create a using declaration that either aliases name to value or inherits the parent methods `name.
Definition: Class.h:544
A declaration for the visibility of subsequent declarations.
Definition: Class.h:595
VisibilityDeclaration(Visibility visibility)
Create a declaration for the given visibility.
Definition: Class.h:598
Visibility getVisibility() const
Get the visibility.
Definition: Class.h:601
void writeDeclTo(raw_indented_ostream &os) const override
Write the visibility declaration.
Visibility
This enum describes C++ inheritance visibility.
Definition: Class.h:408
llvm::raw_ostream & operator<<(llvm::raw_ostream &os, mlir::tblgen::Visibility visibility)
Write "public", "protected", or "private".
std::string stringify(T &&t)
Generically convert a value to a std::string.
Include the generated interface declarations.
Simple RAII struct to use to indentation around entering/exiting region.