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