brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.5 KiB · 52b965b Raw
186 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 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"17 18#include "gmock/gmock.h"19 20using namespace mlir;21 22namespace {23TEST(MLIRParser, ParseInvalidIR) {24  std::string moduleStr = R"mlir(25    module attributes {bad} {}26  )mlir";27 28  MLIRContext context;29  ParserConfig config(&context, /*verifyAfterParse=*/false);30 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)));35}36 37TEST(MLIRParser, ParseAtEnd) {38  std::string firstModuleStr = R"mlir(39    "test.first"() : () -> ()40  )mlir";41  std::string secondModuleStr = R"mlir(42    "test.second"() : () -> ()43  )mlir";44 45  MLIRContext context;46  context.allowUnregisteredDialects();47  Block block;48 49  // Parse the first module string.50  LogicalResult firstParse =51      parseSourceString(firstModuleStr, &block, &context);52  EXPECT_TRUE(succeeded(firstParse));53 54  // Parse the second module string.55  LogicalResult secondParse =56      parseSourceString(secondModuleStr, &block, &context);57  EXPECT_TRUE(succeeded(secondParse));58 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");62}63 64TEST(MLIRParser, ParseAttr) {65  using namespace testing;66  MLIRContext context;67  Builder b(&context);68  { // Successful parse69    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());74  }75  { // Failed parse76    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));85  }86  { // Parse with trailing characters87    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'"));96 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 whitespace101  }102  { // Parse without null-terminator103    StringRef attrAsm("999", 1);104    Attribute attr = parseAttribute(attrAsm, &context);105    EXPECT_EQ(attr, b.getI64IntegerAttr(9));106  }107}108 109TEST(MLIRParser, AsmParserLocations) {110  std::string moduleStr = R"mlir(111func.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>114}115  )mlir";116 117  DialectRegistry registry;118  registry.insert<func::FuncDialect, LLVM::LLVMDialect>();119  MLIRContext context(registry);120 121  auto memBuffer =122      llvm::MemoryBuffer::getMemBuffer(moduleStr, "AsmParserTest.mlir",123                                       /*RequiresNullTerminator=*/false);124  ASSERT_TRUE(memBuffer);125 126  llvm::SourceMgr sourceMgr;127  sourceMgr.AddNewSourceBuffer(std::move(memBuffer), llvm::SMLoc());128 129  Block block;130  AsmParserState parseState;131  const LogicalResult parseResult =132      parseAsmSourceFile(sourceMgr, &block, &context, &parseState);133  ASSERT_TRUE(parseResult.succeeded());134 135  auto funcOp = *block.getOps<func::FuncOp>().begin();136  const AsmParserState::OperationDefinition *funcOpDefinition =137      parseState.getOpDef(funcOp);138  ASSERT_TRUE(funcOpDefinition);139 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);150 151  auto llvmUndef = *funcOp.getOps<LLVM::UndefOp>().begin();152  const AsmParserState::OperationDefinition *llvmUndefDefinition =153      parseState.getOpDef(llvmUndef);154  ASSERT_TRUE(llvmUndefDefinition);155 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);167 168  auto funcReturn = *funcOp.getOps<func::ReturnOp>().begin();169  const AsmParserState::OperationDefinition *funcReturnDefinition =170      parseState.getOpDef(funcReturn);171  ASSERT_TRUE(funcReturnDefinition);172 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);184}185} // namespace186