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