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
38namespace mlir {
39namespace tblgen {
40class FmtObjectBase;
41
42/// This class contains a single method parameter for a C++ function.
44public:
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
79private:
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.
94public:
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
114private:
115 /// The list of parameters.
117};
118
119/// This class contains the signature of a C++ method, including the return
120/// type. method name, and method parameters.
122public:
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
189private:
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.
202public:
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.
252
253private:
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.
267public:
268 virtual ~ClassDeclaration() = default;
269
270 /// Kinds for LLVM-style RTTI.
278 /// Create a class declaration with a given kind.
279 ClassDeclaration(Kind kind) : kind(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
292private:
293 /// The class declaration kind.
294 Kind kind;
295};
296
297/// Base class for class declarations.
298template <ClassDeclaration::Kind DeclKind>
300public:
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
310class Method : public ClassDeclarationBase<ClassDeclaration::Method> {
311public:
312 /// Properties (qualifiers) of class methods. Bitfield is used here to help
313 /// querying properties.
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.
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 {
392 return methodSignature.makesRedundant(other.methodSignature);
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
410protected:
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".
429llvm::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.
433class Constructor : public Method {
434public:
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
479private:
480 /// The list of member 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`.
492 return mlir::tblgen::Method::Properties(static_cast<unsigned>(lhs) |
493 static_cast<unsigned>(rhs));
494}
495
496inline constexpr mlir::tblgen::Method::Properties &
499 return lhs = mlir::tblgen::Method::Properties(static_cast<unsigned>(lhs) |
500 static_cast<unsigned>(rhs));
501}
502
503namespace mlir {
504namespace tblgen {
505
506template <typename ParamT>
507void Method::addTemplateParam(ParamT param) {
508 // Templates imply inline.
510 methodSignature.addTemplateParam(param);
511}
512
513template <typename ContainerT>
514void 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.
522public:
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
542private:
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> {
558public:
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
581private:
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.
593class Field : public ClassDeclarationBase<ClassDeclaration::Field> {
594public:
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
604private:
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.
612class VisibilityDeclaration
613 : public ClassDeclarationBase<ClassDeclaration::VisibilityDeclaration> {
614public:
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
624private:
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.
632class ExtraClassDeclaration
633 : public ClassDeclarationBase<ClassDeclaration::ExtraClassDeclaration> {
634public:
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.
650 void writeDefTo(raw_indented_ostream &os,
651 StringRef namePrefix) const override;
652
653private:
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.
664class Class {
665public:
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;
690 return addConstructorAndPrune(Constructor(getClassName(),
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 const std::vector<std::unique_ptr<Method>> &getMethods() const {
793 return methods;
794 }
795
796 /// Add a new field to the class. Class fields added this way are always
797 /// private.
798 template <typename TypeT, typename NameT>
799 void addField(TypeT &&type, NameT &&name) {
800 fields.emplace_back(std::forward<TypeT>(type), std::forward<NameT>(name));
801 }
802
803 /// Add a parent class.
804 ParentClass &addParent(ParentClass parent);
805
806 /// Add a template parameter.
807 template <typename ParamT>
808 void addTemplateParam(ParamT param) {
809 templateParams.insert(stringify(param));
810 }
811
812 /// Add a list of template parameters.
813 template <typename ContainerT>
814 void addTemplateParams(ContainerT &&container) {
815 templateParams.insert(std::begin(container), std::end(container));
816 }
817
818 /// Return the C++ name of the class.
819 StringRef getClassName() const { return className; }
820
821 /// Write the declaration of this class, all declarations, and definitions of
822 /// inline functions. Wrap the output stream in an indented stream.
823 void writeDeclTo(raw_ostream &rawOs) const {
824 raw_indented_ostream os(rawOs);
825 writeDeclTo(os);
826 }
827 /// Write the definitions of thiss class's out-of-line constructors and
828 /// methods. Wrap the output stream in an indented stream.
829 void writeDefTo(raw_ostream &rawOs) const {
830 raw_indented_ostream os(rawOs);
831 writeDefTo(os);
832 }
833
834 /// Write the declaration of this class, all declarations, and definitions of
835 /// inline functions.
836 void writeDeclTo(raw_indented_ostream &os) const;
837 /// Write the definitions of thiss class's out-of-line constructors and
838 /// methods.
839 void writeDefTo(raw_indented_ostream &os) const;
840
841 /// Add a declaration. The declaration is appended directly to the list of
842 /// class declarations.
843 template <typename DeclT, typename... Args>
844 DeclT *declare(Args &&...args) {
845 auto decl = std::make_unique<DeclT>(std::forward<Args>(args)...);
846 auto *ret = decl.get();
847 declarations.push_back(std::move(decl));
848 return ret;
849 }
850
851 /// The declaration of a class needs to be "finalized".
852 ///
853 /// Class constructors, methods, and fields can be added in any order,
854 /// regardless of whether they are public or private. These are stored in
855 /// lists separate from list of declarations `declarations`.
856 ///
857 /// So that the generated C++ code is somewhat organised, public methods are
858 /// declared together, and so are private methods and class fields. This
859 /// function iterates through all the added methods and fields and organises
860 /// them into the list of declarations, adding visibility declarations as
861 /// needed, as follows:
862 ///
863 /// 1. public methods and constructors
864 /// 2. private methods and constructors
865 /// 3. class fields -- all are private
866 ///
867 /// `Class::finalize` clears the lists of pending methods and fields, and can
868 /// be called multiple times.
869 virtual void finalize();
870
871protected:
872 /// Add a new constructor if it is not made redundant by any existing
873 /// constructors and prune and existing constructors made redundant.
874 Constructor *addConstructorAndPrune(Constructor &&newCtor);
875 /// Add a new method if it is not made redundant by any existing methods and
876 /// prune and existing methods made redundant.
877 Method *addMethodAndPrune(Method &&newMethod);
878
879 /// Get the last visibility declaration.
880 Visibility getLastVisibilityDecl() const;
881
882 /// The C++ class name.
883 std::string className;
884 /// The list of parent classes.
885 SmallVector<ParentClass> parents;
886 /// The pending list of methods and constructors.
887 std::vector<std::unique_ptr<Method>> methods;
888 /// The pending list of private class fields.
889 SmallVector<Field> fields;
890 /// Whether this is a `class` or a `struct`.
892
893 /// A list of declarations in the class, emitted in order.
894 std::vector<std::unique_ptr<ClassDeclaration>> declarations;
895
896 /// An optional list of class template parameters.
898};
899
900} // namespace tblgen
901} // namespace mlir
902
903#endif // MLIR_TABLEGEN_CLASS_H_
constexpr mlir::tblgen::Method::Properties & operator|=(mlir::tblgen::Method::Properties &lhs, mlir::tblgen::Method::Properties rhs)
Definition Class.h:497
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
lhs
raw_ostream subclass that simplifies indention a sequence of code.
Base class for class declarations.
Definition Class.h:299
static bool classof(const ClassDeclaration *other)
Definition Class.h:304
ClassDeclarationBase< DeclKind > Base
Definition Class.h:301
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
void writeTo(raw_indented_ostream &os) const
Write the member initializer.
Definition Class.cpp:238
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 writeDeclTo(raw_indented_ostream &os) const override
Write the declaration of the constructor, and its definition if inline.
Definition Class.cpp:198
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.
Definition Class.cpp:219
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
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
raw_indented_ostream & getStream()
Get the underlying indented output stream.
Definition Class.h:251
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::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
MethodBody & operator<<(ValueT &&value)
Write a value to the method body.
Definition Class.h:221
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
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
Method & operator=(Method &&)=default
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
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
MethodBody & body()
Get the method body.
Definition Class.h:362
Properties
Properties (qualifiers) of class methods.
Definition Class.h:314
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
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
void writeDefTo(raw_indented_ostream &os, StringRef namePrefix) const override
Write the method definition. This is a no-op for inline methods.
Definition Class.cpp:149
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
static bool methodPropertiesAreCompatible(Properties properties)
Utility method to verify method properties correctness.
Definition Class.cpp:162
bool isConst() const
Returns true if this class method is const.
Definition Class.h:382
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 writeTo(raw_indented_ostream &os) const
Write the parent class declaration.
Definition Class.cpp:266
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
bool isStruct
Create a using declaration that either aliases name to value or inherits the parent methods `name.
Definition Class.h:891
SetVector< std::string, SmallVector< std::string >, StringSet<> > templateParams
An optional list of class template parameters.
Definition Class.h:897
std::vector< std::unique_ptr< ClassDeclaration > > declarations
A list of declarations in the class, emitted in order.
Definition Class.h:894
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.
llvm::SetVector< T, Vector, Set, N > SetVector
Definition LLVM.h:131
llvm::StringSet< AllocatorTy > StringSet
Definition LLVM.h:133
Simple RAII struct to use to indentation around entering/exiting region.