10#include "llvm/ADT/Twine.h"
11#include "llvm/Support/Debug.h"
19 return (type.empty() || type.ends_with(
"&") || type.ends_with(
"*")) ?
""
32 os <<
" = " << defaultValue;
46 llvm::interleaveComma(parameters, os,
47 [&os](
auto ¶m) { param.writeDeclTo(os); });
50 llvm::interleaveComma(parameters, os,
51 [&os](
auto ¶m) { param.writeDefTo(os); });
57 if (parameters.size() < other.parameters.size())
60 other.parameters.begin(), other.parameters.end(), parameters.begin(),
61 [](
auto &
lhs,
auto &
rhs) { return lhs.getType() == rhs.getType(); }))
68 return parameters.size() == other.parameters.size() ||
69 parameters[other.parameters.size()].hasDefaultValue();
77 return methodName == other.methodName &&
78 parameters.subsumes(other.parameters);
83 parameters.writeDeclTo(os);
88 StringRef namePrefix)
const {
90 << (namePrefix.empty() ?
"" :
"::") << methodName <<
"(";
91 parameters.writeDefTo(os);
97 if (templateParams.empty())
101 llvm::interleaveComma(templateParams, os,
102 [&](StringRef param) { os <<
"typename " << param; });
111 : declOnly(declOnly), stringOs(body), os(stringOs) {}
114 auto bodyRef = StringRef(body).ltrim(
'\n');
118 if (bodyRef.back() !=
'\n')
129 os <<
"[[deprecated(\"";
173 assert(
false &&
"constructor cannot be static");
177 assert(
false &&
"constructor cannot be const");
182 "declaration implies no definition and thus cannot be inline");
185 if (isDeclaration && isConstexprValue) {
187 "declaration implies no definition and thus cannot be constexpr");
208 if (!initializers.empty())
210 llvm::interleaveComma(initializers, os,
211 [&](
auto &initializer) { initializer.writeTo(os); });
212 if (!initializers.empty())
220 StringRef namePrefix)
const {
227 if (!initializers.empty())
229 llvm::interleaveComma(initializers, os,
230 [&](
auto &initializer) { initializer.writeTo(os); });
231 if (!initializers.empty())
239 os << name <<
'(' << value <<
')';
249 switch (visibility) {
251 return os <<
"public";
253 return os <<
"protected";
255 return os <<
"private";
267 os << visibility <<
' ' << name;
268 if (!templateParams.empty()) {
269 auto scope = os.
scope(
"<",
">",
false);
270 llvm::interleaveComma(templateParams, os,
271 [&](
auto ¶m) { os << param; });
280 if (!templateParams.empty()) {
282 llvm::interleaveComma(templateParams, os, [&](StringRef paramName) {
283 os <<
"typename " << paramName;
287 os <<
"using " << name;
289 os <<
" = " << value;
297void Field::writeDeclTo(raw_indented_ostream &os)
const {
298 os << type <<
' ' << name <<
";\n";
305void VisibilityDeclaration::writeDeclTo(raw_indented_ostream &os)
const {
307 os << visibility <<
":\n";
315void ExtraClassDeclaration::writeDeclTo(raw_indented_ostream &os)
const {
319void ExtraClassDeclaration::writeDefTo(raw_indented_ostream &os,
320 StringRef namePrefix)
const {
328ParentClass &Class::addParent(ParentClass parent) {
329 parents.push_back(std::move(parent));
330 return parents.back();
333void Class::writeDeclTo(raw_indented_ostream &os)
const {
334 if (!templateParams.empty()) {
336 llvm::interleaveComma(templateParams, os,
337 [&](StringRef param) { os <<
"typename " << param; });
342 os << (isStruct ?
"struct" :
"class") <<
' ' << className <<
' ';
345 if (!parents.empty()) {
347 llvm::interleaveComma(parents, os,
348 [&](
auto &parent) { parent.
writeTo(os); });
351 auto classScope = os.
scope(
"{\n",
"};\n",
true);
354 for (
auto &decl : declarations)
355 decl->writeDeclTo(os);
358void Class::writeDefTo(raw_indented_ostream &os)
const {
360 for (
auto &decl : declarations)
361 decl->writeDefTo(os, className);
364void Class::finalize() {
367 SmallVector<std::unique_ptr<Method>> publicMethods, privateMethods;
368 for (
auto &method : methods) {
369 if (method->isPrivate())
370 privateMethods.push_back(std::move(method));
372 publicMethods.push_back(std::move(method));
378 if (!publicMethods.empty() && getLastVisibilityDecl() != Visibility::Public)
379 declare<VisibilityDeclaration>(Visibility::Public);
380 for (
auto &method : publicMethods)
381 declarations.push_back(std::move(method));
385 if (!privateMethods.empty() && getLastVisibilityDecl() != Visibility::Private)
386 declare<VisibilityDeclaration>(Visibility::Private);
387 for (
auto &method : privateMethods)
388 declarations.push_back(std::move(method));
393 if (!fields.empty() && getLastVisibilityDecl() != Visibility::Private)
394 declare<VisibilityDeclaration>(Visibility::Private);
395 for (
auto &field : fields)
396 declare<Field>(std::move(field));
400Visibility Class::getLastVisibilityDecl()
const {
401 auto reverseDecls = llvm::reverse(declarations);
402 auto it = llvm::find_if(reverseDecls, llvm::IsaPred<VisibilityDeclaration>);
403 return it == reverseDecls.end()
404 ? (isStruct ? Visibility::Public : Visibility::Private)
405 : cast<VisibilityDeclaration>(**it).getVisibility();
409 std::unique_ptr<Method> newMethod) {
410 if (llvm::any_of(methods, [&](
auto &method) {
411 return method->makesRedundant(*newMethod);
415 llvm::erase_if(methods, [&](
auto &method) {
416 return newMethod->makesRedundant(*method);
418 methods.push_back(std::move(newMethod));
419 return methods.back().get();
422Method *Class::addMethodAndPrune(Method &&newMethod) {
424 std::make_unique<Method>(std::move(newMethod)));
427Constructor *Class::addConstructorAndPrune(Constructor &&newCtor) {
429 methods, std::make_unique<Constructor>(std::move(newCtor))));
static StringRef getSpaceAfterType(StringRef type)
Returns space to be emitted after the given C++ type.
Method * insertAndPruneMethods(std::vector< std::unique_ptr< Method > > &methods, std::unique_ptr< Method > newMethod)
raw_ostream subclass that simplifies indention a sequence of code.
DelimitedScope scope(StringRef open="", StringRef close="", bool indent=true)
Returns DelimitedScope.
raw_indented_ostream & indent()
Increases the indent and returning this raw_indented_ostream.
raw_indented_ostream & printReindented(StringRef str, StringRef extraPrefix="")
Prints a string re-indented to the current indent.
raw_indented_ostream & unindent()
Decreases the indent and returning this raw_indented_ostream.
virtual void writeDeclTo(raw_indented_ostream &os) const =0
Write the declaration.
void writeTo(raw_indented_ostream &os) const
Write the member initializer.
void writeDeclTo(raw_indented_ostream &os) const override
Write the declaration of the constructor, and its definition if inline.
void writeDefTo(raw_indented_ostream &os, StringRef namePrefix) const override
Write the definition of the constructor if it is not inline.
void writeTo(raw_indented_ostream &os) const
Write the method body to the output stream.
MethodBody(bool declOnly)
Create a method body, indicating whether it should be elided for methods that are declaration-only.
void writeDefTo(raw_indented_ostream &os) const
Write the parameter as part of a method definition.
bool hasDefaultValue() const
Returns true if the parameter has a default value.
void writeDeclTo(raw_indented_ostream &os) const
Write the parameter as part of a method declaration.
void writeDefTo(raw_indented_ostream &os) const
Write the parameters as part of a method definition.
MethodParameters(std::initializer_list< MethodParameter > parameters)
Create a list of method parameters.
bool subsumes(const MethodParameters &other) const
Determine whether this list of parameters "subsumes" another, which occurs when this parameter list i...
void writeDeclTo(raw_indented_ostream &os) const
Write the parameters as part of a method declaration.
MethodSignature(RetTypeT &&retType, NameT &&name, SmallVector< MethodParameter > &¶meters)
Create a method signature with a return type, a method name, and a list of parameters.
bool makesRedundant(const MethodSignature &other) const
Determine whether a method with this signature makes a method with other signature redundant.
void writeDeclTo(raw_indented_ostream &os) const
Write the signature as part of a method declaration.
void writeTemplateParamsTo(raw_indented_ostream &os) const
Write the template parameters of the signature.
void writeDefTo(raw_indented_ostream &os, StringRef namePrefix) const
Write the signature as part of a method definition.
Class for holding an op's method for C++ code emission.
bool isStatic() const
Returns true if this is a static method.
MethodBody methodBody
The body of the method, if it has one.
MethodSignature methodSignature
The signature of the method.
Properties
Properties (qualifiers) of class methods.
void writeDeclTo(raw_indented_ostream &os) const override
Write the method declaration, including the definition if inline.
Properties properties
A collection of method properties.
std::optional< std::string > deprecationMessage
Deprecation message if the method is deprecated.
bool isInline() const
Returns true if this is an inline method.
void writeDefTo(raw_indented_ostream &os, StringRef namePrefix) const override
Write the method definition. This is a no-op for inline methods.
bool isConstructor() const
Returns true if this is a constructor.
static bool methodPropertiesAreCompatible(Properties properties)
Utility method to verify method properties correctness.
bool isConst() const
Returns true if this class method is const.
void writeTo(raw_indented_ostream &os) const
Write the parent class declaration.
Visibility
This enum describes C++ inheritance visibility.
llvm::raw_ostream & operator<<(llvm::raw_ostream &os, mlir::tblgen::Visibility visibility)
Write "public", "protected", or "private".
Include the generated interface declarations.