Mogball b0774e5f50 [mlir][ods] ODS ops get an extraClassDefinition
Extra definitions are placed in the generated source file for each op class. The substitution `$cppClass` is replaced by the op's C++ class name.

This is useful when declaring but not defining methods in TableGen base classes:

```
class BaseOp<string mnemonic>
    : Op<MyDialect, mnemonic, [DeclareOpInterfaceMethods<SomeInterface>] {
  let extraClassDeclaration = [{
    // ZOp is declared at at the bottom of the file and is incomplete here
    ZOp getParent();
  }];
  let extraClassDefinition = [{
    int $cppClass::someInterfaceMethod() {
      return someUtilityFunction(*this);
    }
    ZOp $cppClass::getParent() {
      return dyn_cast<ZOp>(this->getParentOp());
    }
  }];
}
```

Certain things may prevent defining these functions inline, in the declaration. In this example, `ZOp` in the same dialect is incomplete at the function declaration because ops classes are declared in alphabetical order. Alternatively, functions may be too big to be desired as inlined, or they may require dependencies that create cyclic includes, or they may be calling a templated utility function that one may not want to expose in a header. If the functions are not inlined, then inheriting from the base class N times means that each function will need to be defined N times. With `extraClassDefinitions`, they only need to be defined once.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D115783
2022-01-06 01:43:26 +00:00

53 lines
1.8 KiB
C++

//===- OpClass.h - Implementation of an Op Class --------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef MLIR_TOOLS_MLIRTBLGEN_OPCLASS_H_
#define MLIR_TOOLS_MLIRTBLGEN_OPCLASS_H_
#include "mlir/TableGen/Class.h"
namespace mlir {
namespace tblgen {
/// Class for holding an op for C++ code emission. The class is specialized to
/// add Op-specific declarations to the class.
class OpClass : public Class {
public:
/// Create an operation class with extra class declarations, whose default
/// visibility is public. Also declares at the top of the class:
///
/// - inheritance of constructors from `Op`
/// - inheritance of `print`
/// - a type alias for the associated adaptor class
///
OpClass(StringRef name, StringRef extraClassDeclaration,
std::string extraClassDefinition);
/// Add an op trait.
void addTrait(Twine trait) { parent.addTemplateParam(trait.str()); }
/// The operation class is finalized by calling `Class::finalize` to delcare
/// all pending private and public methods (ops don't have custom constructors
/// or fields). Then, the extra class declarations are appended to the end of
/// the class declaration.
void finalize() override;
private:
/// Hand-written extra class declarations.
StringRef extraClassDeclaration;
/// Hand-written extra class definitions.
std::string extraClassDefinition;
/// The parent class, which also contains the traits to be inherited.
ParentClass &parent;
};
} // namespace tblgen
} // namespace mlir
#endif // MLIR_TOOLS_MLIRTBLGEN_OPCLASS_H_