How build a llvm global string using '\0' as end character?

we need a mlir code such llvm.mlir.global linkonce_odr constant @ABC(“abc\00”) , but it cannot be generated by builder. the following code generate these :
llvm.mlir.global linkonce_odr constant @STR(“abc”) {addr_space = 0 : i32}
llvm.mlir.global linkonce_odr constant @STR_0(“abc”) {addr_space = 0 : i32}
llvm.mlir.global linkonce_odr constant @STR_00(“abc”) {addr_space = 0 : i32}
llvm.mlir.global linkonce_odr constant @STR__00(“abc\\00”) {addr_space = 0 : i32}

#include "mlir/IR/Verifier.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"

int main()
{
    mlir::MLIRContext ctx;
    ctx.getOrLoadDialect<mlir::LLVM::LLVMDialect>();

    mlir::OpBuilder builder(&ctx);
    mlir::ModuleOp theModule;
    theModule = mlir::ModuleOp::create(builder.getUnknownLoc());
    builder.setInsertionPointToEnd(theModule.getBody());

    std::string str = "abc";
    std::string str_0 = "abc\0";
    std::string str_00 = "abc\00";
    std::string str__00 = "abc\\00";

    auto str_TY = mlir::LLVM::LLVMArrayType::get(builder.getI8Type(), str.size());
    auto str_0_TY = mlir::LLVM::LLVMArrayType::get(builder.getI8Type(), str_0.size());
    auto str_00_TY = mlir::LLVM::LLVMArrayType::get(builder.getI8Type(), str_00.size());
    auto str__00_TY = mlir::LLVM::LLVMArrayType::get(builder.getI8Type(), str__00.size());

    builder.create<mlir::LLVM::GlobalOp>(builder.getUnknownLoc(), 
        /*type*/str_TY, /*constant*/true, mlir::LLVM::Linkage::LinkonceODR, "STR", builder.getStringAttr(str));
    builder.create<mlir::LLVM::GlobalOp>(builder.getUnknownLoc(), 
        /*type*/str_0_TY, /*constant*/true, mlir::LLVM::Linkage::LinkonceODR, "STR_0", builder.getStringAttr(str_0));
    builder.create<mlir::LLVM::GlobalOp>(builder.getUnknownLoc(), 
        /*type*/str_00_TY, /*constant*/true, mlir::LLVM::Linkage::LinkonceODR, "STR_00", builder.getStringAttr(str_00));
    builder.create<mlir::LLVM::GlobalOp>(builder.getUnknownLoc(), 
        /*type*/str__00_TY, /*constant*/true, mlir::LLVM::Linkage::LinkonceODR, "STR__00", builder.getStringAttr(str__00));

    if(failed(mlir::verify(theModule))) {
        theModule.emitError("module verification error");
    }
    theModule->dump();
    return 0;
}
1 Like

std::string won’t infer the correct length here, try std::string str_0("abc\0", 4), or auto str_0 = llvm::StringLiteral::withInnerNUL("abc\0")

2 Likes

there is a little problem, the string is from the parser, how should i to construct a new string with ‘\0’ by a old string without ‘\0’ ?

std::string::push_back, or you could take advantage of std::string being null-terminated: StringRef(std_string.c_str(), std_string.size() + 1)

1 Like

thank you very much :slight_smile: