[LLVM] Fix Maintainers.md formatting (NFC)
[llvm-project.git] / mlir / unittests / Parser / ParserTest.cpp
blob52b965bcc1326b15d91733614d935f9ea8755c3e
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 //===----------------------------------------------------------------------===//
9 #include "mlir/Parser/Parser.h"
10 #include "mlir/AsmParser/AsmParser.h"
11 #include "mlir/AsmParser/AsmParserState.h"
12 #include "mlir/Dialect/Func/IR/FuncOps.h"
13 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
14 #include "mlir/IR/BuiltinOps.h"
15 #include "mlir/IR/Verifier.h"
16 #include "llvm/Support/SourceMgr.h"
18 #include "gmock/gmock.h"
20 using namespace mlir;
22 namespace {
23 TEST(MLIRParser, ParseInvalidIR) {
24 std::string moduleStr = R"mlir(
25 module attributes {bad} {}
26 )mlir";
28 MLIRContext context;
29 ParserConfig config(&context, /*verifyAfterParse=*/false);
31 // Check that we properly parse the op, but it fails the verifier.
32 OwningOpRef<ModuleOp> module = parseSourceString<ModuleOp>(moduleStr, config);
33 ASSERT_TRUE(module);
34 ASSERT_TRUE(failed(verify(*module)));
37 TEST(MLIRParser, ParseAtEnd) {
38 std::string firstModuleStr = R"mlir(
39 "test.first"() : () -> ()
40 )mlir";
41 std::string secondModuleStr = R"mlir(
42 "test.second"() : () -> ()
43 )mlir";
45 MLIRContext context;
46 context.allowUnregisteredDialects();
47 Block block;
49 // Parse the first module string.
50 LogicalResult firstParse =
51 parseSourceString(firstModuleStr, &block, &context);
52 EXPECT_TRUE(succeeded(firstParse));
54 // Parse the second module string.
55 LogicalResult secondParse =
56 parseSourceString(secondModuleStr, &block, &context);
57 EXPECT_TRUE(succeeded(secondParse));
59 // Check the we parse at the end.
60 EXPECT_EQ(block.front().getName().getStringRef(), "test.first");
61 EXPECT_EQ(block.back().getName().getStringRef(), "test.second");
64 TEST(MLIRParser, ParseAttr) {
65 using namespace testing;
66 MLIRContext context;
67 Builder b(&context);
68 { // Successful parse
69 StringLiteral attrAsm = "array<i64: 1, 2, 3>";
70 size_t numRead = 0;
71 Attribute attr = parseAttribute(attrAsm, &context, Type(), &numRead);
72 EXPECT_EQ(attr, b.getDenseI64ArrayAttr({1, 2, 3}));
73 EXPECT_EQ(numRead, attrAsm.size());
75 { // Failed parse
76 std::vector<std::string> diagnostics;
77 ScopedDiagnosticHandler handler(&context, [&](Diagnostic &d) {
78 llvm::raw_string_ostream(diagnostics.emplace_back())
79 << d.getLocation() << ": " << d;
80 });
81 size_t numRead = 0;
82 EXPECT_FALSE(parseAttribute("dense<>", &context, Type(), &numRead));
83 EXPECT_THAT(diagnostics, ElementsAre("loc(\"dense<>\":1:7): expected ':'"));
84 EXPECT_EQ(numRead, size_t(0));
86 { // Parse with trailing characters
87 std::vector<std::string> diagnostics;
88 ScopedDiagnosticHandler handler(&context, [&](Diagnostic &d) {
89 llvm::raw_string_ostream(diagnostics.emplace_back())
90 << d.getLocation() << ": " << d;
91 });
92 EXPECT_FALSE(parseAttribute("10 foo", &context));
93 EXPECT_THAT(
94 diagnostics,
95 ElementsAre("loc(\"10 foo\":1:5): found trailing characters: 'foo'"));
97 size_t numRead = 0;
98 EXPECT_EQ(parseAttribute("10 foo", &context, Type(), &numRead),
99 b.getI64IntegerAttr(10));
100 EXPECT_EQ(numRead, size_t(4)); // includes trailing whitespace
102 { // Parse without null-terminator
103 StringRef attrAsm("999", 1);
104 Attribute attr = parseAttribute(attrAsm, &context);
105 EXPECT_EQ(attr, b.getI64IntegerAttr(9));
109 TEST(MLIRParser, AsmParserLocations) {
110 std::string moduleStr = R"mlir(
111 func.func @foo() -> !llvm.array<2 x f32> {
112 %0 = llvm.mlir.undef : !llvm.array<2 x f32>
113 func.return %0 : !llvm.array<2 x f32>
115 )mlir";
117 DialectRegistry registry;
118 registry.insert<func::FuncDialect, LLVM::LLVMDialect>();
119 MLIRContext context(registry);
121 auto memBuffer =
122 llvm::MemoryBuffer::getMemBuffer(moduleStr, "AsmParserTest.mlir",
123 /*RequiresNullTerminator=*/false);
124 ASSERT_TRUE(memBuffer);
126 llvm::SourceMgr sourceMgr;
127 sourceMgr.AddNewSourceBuffer(std::move(memBuffer), llvm::SMLoc());
129 Block block;
130 AsmParserState parseState;
131 const LogicalResult parseResult =
132 parseAsmSourceFile(sourceMgr, &block, &context, &parseState);
133 ASSERT_TRUE(parseResult.succeeded());
135 auto funcOp = *block.getOps<func::FuncOp>().begin();
136 const AsmParserState::OperationDefinition *funcOpDefinition =
137 parseState.getOpDef(funcOp);
138 ASSERT_TRUE(funcOpDefinition);
140 const std::pair expectedStartFunc{2u, 1u};
141 const std::pair expectedEndFunc{2u, 10u};
142 const std::pair expectedScopeEndFunc{5u, 2u};
143 ASSERT_EQ(sourceMgr.getLineAndColumn(funcOpDefinition->loc.Start),
144 expectedStartFunc);
145 ASSERT_EQ(sourceMgr.getLineAndColumn(funcOpDefinition->loc.End),
146 expectedEndFunc);
147 ASSERT_EQ(funcOpDefinition->loc.Start, funcOpDefinition->scopeLoc.Start);
148 ASSERT_EQ(sourceMgr.getLineAndColumn(funcOpDefinition->scopeLoc.End),
149 expectedScopeEndFunc);
151 auto llvmUndef = *funcOp.getOps<LLVM::UndefOp>().begin();
152 const AsmParserState::OperationDefinition *llvmUndefDefinition =
153 parseState.getOpDef(llvmUndef);
154 ASSERT_TRUE(llvmUndefDefinition);
156 const std::pair expectedStartUndef{3u, 8u};
157 const std::pair expectedEndUndef{3u, 23u};
158 const std::pair expectedScopeEndUndef{3u, 46u};
159 ASSERT_EQ(sourceMgr.getLineAndColumn(llvmUndefDefinition->loc.Start),
160 expectedStartUndef);
161 ASSERT_EQ(sourceMgr.getLineAndColumn(llvmUndefDefinition->loc.End),
162 expectedEndUndef);
163 ASSERT_EQ(llvmUndefDefinition->loc.Start,
164 llvmUndefDefinition->scopeLoc.Start);
165 ASSERT_EQ(sourceMgr.getLineAndColumn(llvmUndefDefinition->scopeLoc.End),
166 expectedScopeEndUndef);
168 auto funcReturn = *funcOp.getOps<func::ReturnOp>().begin();
169 const AsmParserState::OperationDefinition *funcReturnDefinition =
170 parseState.getOpDef(funcReturn);
171 ASSERT_TRUE(funcReturnDefinition);
173 const std::pair expectedStartReturn{4u, 3u};
174 const std::pair expectedEndReturn{4u, 14u};
175 const std::pair expectedScopeEndReturn{4u, 40u};
176 ASSERT_EQ(sourceMgr.getLineAndColumn(funcReturnDefinition->loc.Start),
177 expectedStartReturn);
178 ASSERT_EQ(sourceMgr.getLineAndColumn(funcReturnDefinition->loc.End),
179 expectedEndReturn);
180 ASSERT_EQ(funcReturnDefinition->loc.Start,
181 funcReturnDefinition->scopeLoc.Start);
182 ASSERT_EQ(sourceMgr.getLineAndColumn(funcReturnDefinition->scopeLoc.End),
183 expectedScopeEndReturn);
185 } // namespace