diff --git a/llvm/test/tools/llvm-mc/doc-id-disassemble.s b/llvm/test/tools/llvm-mc/doc-id-disassemble.s new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-mc/doc-id-disassemble.s @@ -0,0 +1,15 @@ +# REQUIRES: x86-registered-target +# RUN: llvm-mc -triple=x86_64 --disassemble --doc-id=aa %s | \ +# RUN: FileCheck %s --check-prefix=AA --implicit-check-not=retq + +# AA: nop + +# RUN: llvm-mc -triple=x86_64 --disassemble --doc-id=bb %s | \ +# RUN: FileCheck %s --check-prefix=BB --implicit-check-not=nop + +# BB: retq + +#-- aa +0x90 +#-- bb +0xc3 diff --git a/llvm/test/tools/llvm-mc/doc-id.s b/llvm/test/tools/llvm-mc/doc-id.s new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-mc/doc-id.s @@ -0,0 +1,26 @@ +# RUN: llvm-mc --doc-id=aa --preserve-comments %s 2>&1 | FileCheck %s --check-prefix=AA --implicit-check-not=warning: + +# AA: {{.*}}.s:1:1: warning: aa +# AA: # Comments are preserved. + +# RUN: llvm-mc --doc-id=bb %s 2>&1 | FileCheck %s --check-prefix=BB --implicit-check-not=warning: + +# BB: {{.*}}.s:2:1: warning: bb + +# RUN: not llvm-mc --doc-id=dup %s 2>&1 | FileCheck %s --check-prefix=DUP + +# DUP: error: {{.*}}.s: '#-- dup' occurred more than once + +# RUN: not llvm-mc --doc-id=not_exist %s 2>&1 | FileCheck %s --check-prefix=NOT_EXIST + +# NOT_EXIST: error: {{.*}}.s: '#-- not_exist' not found + +#-- aa +.warning "aa" +# Comments are preserved. +#-- bb + +.warning "bb" +#-- dup +.warning "dup" +#-- dup diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp --- a/llvm/tools/llvm-mc/llvm-mc.cpp +++ b/llvm/tools/llvm-mc/llvm-mc.cpp @@ -32,7 +32,9 @@ #include "llvm/Support/FormattedStream.h" #include "llvm/Support/Host.h" #include "llvm/Support/InitLLVM.h" +#include "llvm/Support/LineIterator.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SmallVectorMemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" @@ -46,6 +48,12 @@ static cl::opt InputFilename(cl::Positional, cl::desc(""), cl::init("-")); +static cl::opt DocId( + "doc-id", + cl::desc("Treat input as separated by \"--- \", feed the part specified " + "by \"--- \" to assembler/disassembler"), + cl::value_desc("id")); + static cl::opt OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-")); @@ -306,6 +314,37 @@ return Res; } +static void handleDocId(std::unique_ptr &Buf, StringRef ProgName, + StringRef FileName) { + const char *DocBegin = nullptr, *DocEnd = nullptr; + for (line_iterator I(*Buf, /*SkipBlanks=*/false, '\0'); !I.is_at_eof();) { + StringRef Line = *I++; + if (!Line.consume_front("#-- ")) + continue; + if (Line == DocId.getValue()) { + if (DocBegin) { + WithColor::error(errs(), ProgName) + << FileName << ": '#-- " << Line << "' occurred more than once\n"; + exit(1); + } + if (I.is_at_eof()) + break; + DocBegin = I->data(); + } else if (DocBegin && !DocEnd) { + DocEnd = Line.data(); + } + } + if (!DocBegin) { + WithColor::error(errs(), ProgName) + << FileName << ": '#-- " << DocId << "' not found\n"; + exit(1); + } + if (!DocEnd) + DocEnd = Buf->getBufferEnd(); + Buf.reset(new SmallVectorMemoryBuffer(SmallVector(DocBegin, DocEnd), + Buf->getBufferIdentifier())); +} + int main(int argc, char **argv) { InitLLVM X(argc, argv); @@ -339,6 +378,8 @@ << InputFilename << ": " << EC.message() << '\n'; return 1; } + if (!DocId.empty()) + handleDocId(*BufferPtr, ProgName, InputFilename); MemoryBuffer *Buffer = BufferPtr->get(); SourceMgr SrcMgr;