1//===- ParserTest.cpp -----------------------------------------------------===//
2//
3// This file is licensed 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#include "mlir/Parser/Parser.h"
10#include "mlir/AsmParser/AsmParser.h"
11#include "mlir/IR/BuiltinOps.h"
12#include "mlir/IR/Verifier.h"
13
14#include "gmock/gmock.h"
15
16using namespace mlir;
17
18namespace {
19TEST(MLIRParser, ParseInvalidIR) {
20 std::string moduleStr = R"mlir(
21 module attributes {bad} {}
22 )mlir";
23
24 MLIRContext context;
25 ParserConfig config(&context, /*verifyAfterParse=*/false);
26
27 // Check that we properly parse the op, but it fails the verifier.
28 OwningOpRef<ModuleOp> module = parseSourceString<ModuleOp>(moduleStr, config);
29 ASSERT_TRUE(module);
30 ASSERT_TRUE(failed(verify(*module)));
31}
32
33TEST(MLIRParser, ParseAtEnd) {
34 std::string firstModuleStr = R"mlir(
35 "test.first"() : () -> ()
36 )mlir";
37 std::string secondModuleStr = R"mlir(
38 "test.second"() : () -> ()
39 )mlir";
40
41 MLIRContext context;
42 context.allowUnregisteredDialects();
43 Block block;
44
45 // Parse the first module string.
46 LogicalResult firstParse =
47 parseSourceString(sourceStr: firstModuleStr, block: &block, config: &context);
48 EXPECT_TRUE(succeeded(firstParse));
49
50 // Parse the second module string.
51 LogicalResult secondParse =
52 parseSourceString(sourceStr: secondModuleStr, block: &block, config: &context);
53 EXPECT_TRUE(succeeded(secondParse));
54
55 // Check the we parse at the end.
56 EXPECT_EQ(block.front().getName().getStringRef(), "test.first");
57 EXPECT_EQ(block.back().getName().getStringRef(), "test.second");
58}
59
60TEST(MLIRParser, ParseAttr) {
61 using namespace testing;
62 MLIRContext context;
63 Builder b(&context);
64 { // Successful parse
65 StringLiteral attrAsm = "array<i64: 1, 2, 3>";
66 size_t numRead = 0;
67 Attribute attr = parseAttribute(attrStr: attrAsm, context: &context, type: Type(), numRead: &numRead);
68 EXPECT_EQ(attr, b.getDenseI64ArrayAttr({1, 2, 3}));
69 EXPECT_EQ(numRead, attrAsm.size());
70 }
71 { // Failed parse
72 std::vector<std::string> diagnostics;
73 ScopedDiagnosticHandler handler(&context, [&](Diagnostic &d) {
74 llvm::raw_string_ostream(diagnostics.emplace_back())
75 << d.getLocation() << ": " << d;
76 });
77 size_t numRead = 0;
78 EXPECT_FALSE(parseAttribute("dense<>", &context, Type(), &numRead));
79 EXPECT_THAT(diagnostics, ElementsAre("loc(\"dense<>\":1:7): expected ':'"));
80 EXPECT_EQ(numRead, size_t(0));
81 }
82 { // Parse with trailing characters
83 std::vector<std::string> diagnostics;
84 ScopedDiagnosticHandler handler(&context, [&](Diagnostic &d) {
85 llvm::raw_string_ostream(diagnostics.emplace_back())
86 << d.getLocation() << ": " << d;
87 });
88 EXPECT_FALSE(parseAttribute("10 foo", &context));
89 EXPECT_THAT(
90 diagnostics,
91 ElementsAre("loc(\"10 foo\":1:5): found trailing characters: 'foo'"));
92
93 size_t numRead = 0;
94 EXPECT_EQ(parseAttribute("10 foo", &context, Type(), &numRead),
95 b.getI64IntegerAttr(10));
96 EXPECT_EQ(numRead, size_t(4)); // includes trailing whitespace
97 }
98 { // Parse without null-terminator
99 StringRef attrAsm("999", 1);
100 Attribute attr = parseAttribute(attrStr: attrAsm, context: &context);
101 EXPECT_EQ(attr, b.getI64IntegerAttr(9));
102 }
103}
104} // namespace
105

source code of mlir/unittests/Parser/ParserTest.cpp