| //===- Parser.h - MLIR Parser Library Interface -----------------*- C++ -*-===// |
| // |
| // 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 |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file is contains the interface to the MLIR parser library. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef MLIR_PARSER_H |
| #define MLIR_PARSER_H |
| |
| #include "mlir/IR/Builders.h" |
| #include "mlir/IR/BuiltinOps.h" |
| #include <cstddef> |
| |
| namespace llvm { |
| class SourceMgr; |
| class SMDiagnostic; |
| class StringRef; |
| } // end namespace llvm |
| |
| namespace mlir { |
| class AsmParserState; |
| |
| namespace detail { |
| |
| /// Given a block containing operations that have just been parsed, if the block |
| /// contains a single operation of `ContainerOpT` type then remove it from the |
| /// block and return it. If the block does not contain just that operation, |
| /// create a new operation instance of `ContainerOpT` and move all of the |
| /// operations within `parsedBlock` into the first block of the first region. |
| /// `ContainerOpT` is required to have a single region containing a single |
| /// block, and must implement the `SingleBlockImplicitTerminator` trait. |
| template <typename ContainerOpT> |
| inline OwningOpRef<ContainerOpT> constructContainerOpForParserIfNecessary( |
| Block *parsedBlock, MLIRContext *context, Location sourceFileLoc) { |
| static_assert( |
| ContainerOpT::template hasTrait<OpTrait::OneRegion>() && |
| (ContainerOpT::template hasTrait<OpTrait::NoTerminator>() || |
| OpTrait::template hasSingleBlockImplicitTerminator< |
| ContainerOpT>::value), |
| "Expected `ContainerOpT` to have a single region with a single " |
| "block that has an implicit terminator or does not require one"); |
| |
| // Check to see if we parsed a single instance of this operation. |
| if (llvm::hasSingleElement(*parsedBlock)) { |
| if (ContainerOpT op = dyn_cast<ContainerOpT>(parsedBlock->front())) { |
| op->remove(); |
| return op; |
| } |
| } |
| |
| // If not, then build a new one to contain the parsed operations. |
| OpBuilder builder(context); |
| ContainerOpT op = builder.create<ContainerOpT>(sourceFileLoc); |
| OwningOpRef<ContainerOpT> opRef(op); |
| assert(op->getNumRegions() == 1 && llvm::hasSingleElement(op->getRegion(0)) && |
| "expected generated operation to have a single region with a single " |
| "block"); |
| Block *opBlock = &op->getRegion(0).front(); |
| opBlock->getOperations().splice(opBlock->begin(), |
| parsedBlock->getOperations()); |
| |
| // After splicing, verify just this operation to ensure it can properly |
| // contain the operations inside of it. |
| if (failed(op.verify())) |
| return OwningOpRef<ContainerOpT>(); |
| return opRef; |
| } |
| } // end namespace detail |
| |
| /// This parses the file specified by the indicated SourceMgr and appends parsed |
| /// operations to the given block. If the block is non-empty, the operations are |
| /// placed before the current terminator. If parsing is successful, success is |
| /// returned. Otherwise, an error message is emitted through the error handler |
| /// registered in the context, and failure is returned. If `sourceFileLoc` is |
| /// non-null, it is populated with a file location representing the start of the |
| /// source file that is being parsed. If `asmState` is non-null, it is populated |
| /// with detailed information about the parsed IR (including exact locations for |
| /// SSA uses and definitions). `asmState` should only be provided if this |
| /// detailed information is desired. |
| LogicalResult parseSourceFile(const llvm::SourceMgr &sourceMgr, Block *block, |
| MLIRContext *context, |
| LocationAttr *sourceFileLoc = nullptr, |
| AsmParserState *asmState = nullptr); |
| |
| /// This parses the file specified by the indicated filename and appends parsed |
| /// operations to the given block. If the block is non-empty, the operations are |
| /// placed before the current terminator. If parsing is successful, success is |
| /// returned. Otherwise, an error message is emitted through the error handler |
| /// registered in the context, and failure is returned. If `sourceFileLoc` is |
| /// non-null, it is populated with a file location representing the start of the |
| /// source file that is being parsed. |
| LogicalResult parseSourceFile(llvm::StringRef filename, Block *block, |
| MLIRContext *context, |
| LocationAttr *sourceFileLoc = nullptr); |
| |
| /// This parses the file specified by the indicated filename using the provided |
| /// SourceMgr and appends parsed operations to the given block. If the block is |
| /// non-empty, the operations are placed before the current terminator. If |
| /// parsing is successful, success is returned. Otherwise, an error message is |
| /// emitted through the error handler registered in the context, and failure is |
| /// returned. If `sourceFileLoc` is non-null, it is populated with a file |
| /// location representing the start of the source file that is being parsed. If |
| /// `asmState` is non-null, it is populated with detailed information about the |
| /// parsed IR (including exact locations for SSA uses and definitions). |
| /// `asmState` should only be provided if this detailed information is desired. |
| LogicalResult parseSourceFile(llvm::StringRef filename, |
| llvm::SourceMgr &sourceMgr, Block *block, |
| MLIRContext *context, |
| LocationAttr *sourceFileLoc = nullptr, |
| AsmParserState *asmState = nullptr); |
| |
| /// This parses the IR string and appends parsed operations to the given block. |
| /// If the block is non-empty, the operations are placed before the current |
| /// terminator. If parsing is successful, success is returned. Otherwise, an |
| /// error message is emitted through the error handler registered in the |
| /// context, and failure is returned. If `sourceFileLoc` is non-null, it is |
| /// populated with a file location representing the start of the source file |
| /// that is being parsed. |
| LogicalResult parseSourceString(llvm::StringRef sourceStr, Block *block, |
| MLIRContext *context, |
| LocationAttr *sourceFileLoc = nullptr); |
| |
| /// This parses the file specified by the indicated SourceMgr. If the source IR |
| /// contained a single instance of `ContainerOpT`, it is returned. Otherwise, a |
| /// new instance of `ContainerOpT` is constructed containing all of the parsed |
| /// operations. If parsing was not successful, null is returned and an error |
| /// message is emitted through the error handler registered in the context, and |
| /// failure is returned. `ContainerOpT` is required to have a single region |
| /// containing a single block, and must implement the |
| /// `SingleBlockImplicitTerminator` trait. |
| template <typename ContainerOpT> |
| inline OwningOpRef<ContainerOpT> |
| parseSourceFile(const llvm::SourceMgr &sourceMgr, MLIRContext *context) { |
| LocationAttr sourceFileLoc; |
| Block block; |
| if (failed(parseSourceFile(sourceMgr, &block, context, &sourceFileLoc))) |
| return OwningOpRef<ContainerOpT>(); |
| return detail::constructContainerOpForParserIfNecessary<ContainerOpT>( |
| &block, context, sourceFileLoc); |
| } |
| |
| /// This parses the file specified by the indicated filename. If the source IR |
| /// contained a single instance of `ContainerOpT`, it is returned. Otherwise, a |
| /// new instance of `ContainerOpT` is constructed containing all of the parsed |
| /// operations. If parsing was not successful, null is returned and an error |
| /// message is emitted through the error handler registered in the context, and |
| /// failure is returned. `ContainerOpT` is required to have a single region |
| /// containing a single block, and must implement the |
| /// `SingleBlockImplicitTerminator` trait. |
| template <typename ContainerOpT> |
| inline OwningOpRef<ContainerOpT> parseSourceFile(llvm::StringRef filename, |
| MLIRContext *context) { |
| LocationAttr sourceFileLoc; |
| Block block; |
| if (failed(parseSourceFile(filename, &block, context, &sourceFileLoc))) |
| return OwningOpRef<ContainerOpT>(); |
| return detail::constructContainerOpForParserIfNecessary<ContainerOpT>( |
| &block, context, sourceFileLoc); |
| } |
| |
| /// This parses the file specified by the indicated filename using the provided |
| /// SourceMgr. If the source IR contained a single instance of `ContainerOpT`, |
| /// it is returned. Otherwise, a new instance of `ContainerOpT` is constructed |
| /// containing all of the parsed operations. If parsing was not successful, null |
| /// is returned and an error message is emitted through the error handler |
| /// registered in the context, and failure is returned. `ContainerOpT` is |
| /// required to have a single region containing a single block, and must |
| /// implement the `SingleBlockImplicitTerminator` trait. |
| template <typename ContainerOpT> |
| inline OwningOpRef<ContainerOpT> parseSourceFile(llvm::StringRef filename, |
| llvm::SourceMgr &sourceMgr, |
| MLIRContext *context) { |
| LocationAttr sourceFileLoc; |
| Block block; |
| if (failed(parseSourceFile(filename, sourceMgr, &block, context, |
| &sourceFileLoc))) |
| return OwningOpRef<ContainerOpT>(); |
| return detail::constructContainerOpForParserIfNecessary<ContainerOpT>( |
| &block, context, sourceFileLoc); |
| } |
| |
| /// This parses the provided string containing MLIR. If the source IR contained |
| /// a single instance of `ContainerOpT`, it is returned. Otherwise, a new |
| /// instance of `ContainerOpT` is constructed containing all of the parsed |
| /// operations. If parsing was not successful, null is returned and an error |
| /// message is emitted through the error handler registered in the context, and |
| /// failure is returned. `ContainerOpT` is required to have a single region |
| /// containing a single block, and must implement the |
| /// `SingleBlockImplicitTerminator` trait. |
| template <typename ContainerOpT> |
| inline OwningOpRef<ContainerOpT> parseSourceString(llvm::StringRef sourceStr, |
| MLIRContext *context) { |
| LocationAttr sourceFileLoc; |
| Block block; |
| if (failed(parseSourceString(sourceStr, &block, context, &sourceFileLoc))) |
| return OwningOpRef<ContainerOpT>(); |
| return detail::constructContainerOpForParserIfNecessary<ContainerOpT>( |
| &block, context, sourceFileLoc); |
| } |
| |
| /// TODO: These methods are deprecated in favor of the above template versions. |
| /// They should be removed when usages have been updated. |
| inline OwningModuleRef parseSourceFile(const llvm::SourceMgr &sourceMgr, |
| MLIRContext *context) { |
| return parseSourceFile<ModuleOp>(sourceMgr, context); |
| } |
| inline OwningModuleRef parseSourceFile(llvm::StringRef filename, |
| MLIRContext *context) { |
| return parseSourceFile<ModuleOp>(filename, context); |
| } |
| inline OwningModuleRef parseSourceFile(llvm::StringRef filename, |
| llvm::SourceMgr &sourceMgr, |
| MLIRContext *context) { |
| return parseSourceFile<ModuleOp>(filename, sourceMgr, context); |
| } |
| inline OwningModuleRef parseSourceString(llvm::StringRef moduleStr, |
| MLIRContext *context) { |
| return parseSourceString<ModuleOp>(moduleStr, context); |
| } |
| |
| /// This parses a single MLIR attribute to an MLIR context if it was valid. If |
| /// not, an error message is emitted through a new SourceMgrDiagnosticHandler |
| /// constructed from a new SourceMgr with a single a MemoryBuffer wrapping |
| /// `attrStr`. If the passed `attrStr` has additional tokens that were not part |
| /// of the type, an error is emitted. |
| // TODO: Improve diagnostic reporting. |
| Attribute parseAttribute(llvm::StringRef attrStr, MLIRContext *context); |
| Attribute parseAttribute(llvm::StringRef attrStr, Type type); |
| |
| /// This parses a single MLIR attribute to an MLIR context if it was valid. If |
| /// not, an error message is emitted through a new SourceMgrDiagnosticHandler |
| /// constructed from a new SourceMgr with a single a MemoryBuffer wrapping |
| /// `attrStr`. The number of characters of `attrStr` parsed in the process is |
| /// returned in `numRead`. |
| Attribute parseAttribute(llvm::StringRef attrStr, MLIRContext *context, |
| size_t &numRead); |
| Attribute parseAttribute(llvm::StringRef attrStr, Type type, size_t &numRead); |
| |
| /// This parses a single MLIR type to an MLIR context if it was valid. If not, |
| /// an error message is emitted through a new SourceMgrDiagnosticHandler |
| /// constructed from a new SourceMgr with a single a MemoryBuffer wrapping |
| /// `typeStr`. If the passed `typeStr` has additional tokens that were not part |
| /// of the type, an error is emitted. |
| // TODO: Improve diagnostic reporting. |
| Type parseType(llvm::StringRef typeStr, MLIRContext *context); |
| |
| /// This parses a single MLIR type to an MLIR context if it was valid. If not, |
| /// an error message is emitted through a new SourceMgrDiagnosticHandler |
| /// constructed from a new SourceMgr with a single a MemoryBuffer wrapping |
| /// `typeStr`. The number of characters of `typeStr` parsed in the process is |
| /// returned in `numRead`. |
| Type parseType(llvm::StringRef typeStr, MLIRContext *context, size_t &numRead); |
| |
| /// This parses a single IntegerSet to an MLIR context if it was valid. If not, |
| /// an error message is emitted through a new SourceMgrDiagnosticHandler |
| /// constructed from a new SourceMgr with a single MemoryBuffer wrapping |
| /// `str`. If the passed `str` has additional tokens that were not part of the |
| /// IntegerSet, a failure is returned. Diagnostics are printed on failure if |
| /// `printDiagnosticInfo` is true. |
| IntegerSet parseIntegerSet(llvm::StringRef str, MLIRContext *context, |
| bool printDiagnosticInfo = true); |
| |
| } // end namespace mlir |
| |
| #endif // MLIR_PARSER_H |