Skip to content

Commit ca7f55e

Browse files
committed
[LLVM-C] Add binding to BitcodeReader::getBitcodeProducerString
Add `LLVMGetBircodeProducerString` function in LLVM C API that binds to `BitcodeReader::getBitcodeProducerString` in LLVM C++ API.
1 parent 138e0ff commit ca7f55e

File tree

6 files changed

+73
-2
lines changed

6 files changed

+73
-2
lines changed

llvm/include/llvm-c/BitReader.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ LLVM_C_ABI LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf,
8484
LLVM_C_ABI LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,
8585
LLVMModuleRef *OutM);
8686

87+
/**
88+
* Reads the producer string from the bitcode header in the given memory
89+
* buffer. Returns 0 on success. The produced string must be disposed with
90+
* LLVMDisposeMessage.
91+
*/
92+
LLVM_C_ABI LLVMBool LLVMGetBitcodeProducerString(LLVMMemoryBufferRef MemBuf,
93+
char **OutProducer,
94+
char **OutMessage);
95+
8796
/**
8897
* @}
8998
*/

llvm/lib/Bitcode/Reader/BitReader.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,24 @@ LLVMBool LLVMGetBitcodeModule2(LLVMMemoryBufferRef MemBuf,
130130
LLVMModuleRef *OutM) {
131131
return LLVMGetBitcodeModuleInContext2(LLVMGetGlobalContext(), MemBuf, OutM);
132132
}
133+
134+
LLVMBool LLVMGetBitcodeProducerString(LLVMMemoryBufferRef MemBuf,
135+
char **OutProducer, char **OutMessage) {
136+
MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef();
137+
138+
Expected<std::string> ProducerOrErr = getBitcodeProducerString(Buf);
139+
if (!ProducerOrErr) {
140+
std::string Message;
141+
handleAllErrors(ProducerOrErr.takeError(),
142+
[&](ErrorInfoBase &EIB) { Message = EIB.message(); });
143+
if (OutMessage)
144+
*OutMessage = strdup(Message.c_str());
145+
if (OutProducer)
146+
*OutProducer = nullptr;
147+
return 1;
148+
}
149+
150+
if (OutProducer)
151+
*OutProducer = strdup(ProducerOrErr->c_str());
152+
return 0;
153+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
; RUN: llvm-as < %s | llvm-c-test --module-get-producer-string | FileCheck %s
2+
; CHECK: LLVM{{[0-9]+.*}}

llvm/tools/llvm-c-test/llvm-c-test.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ LLVMModuleRef llvm_load_module(LLVMContextRef C, bool Lazy, bool New);
2828
int llvm_module_dump(bool Lazy, bool New);
2929
int llvm_module_list_functions(void);
3030
int llvm_module_list_globals(void);
31+
int llvm_module_get_producer_string(void);
3132

3233
// calc.c
3334
int llvm_calc(void);

llvm/tools/llvm-c-test/main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ static void print_usage(void) {
3333
" Read bitcode from stdin - list summary of functions\n\n");
3434
fprintf(stderr, " * --module-list-globals\n");
3535
fprintf(stderr, " Read bitcode from stdin - list summary of globals\n\n");
36+
fprintf(stderr, " * --module-get-producer-string\n");
37+
fprintf(
38+
stderr,
39+
" Read bitcode from stdin - print the producer identification\n\n");
3640
fprintf(stderr, " * --targets-list\n");
3741
fprintf(stderr, " List available targets\n\n");
3842
fprintf(stderr, " * --object-list-sections\n");
@@ -79,6 +83,8 @@ int main(int argc, char **argv) {
7983
return llvm_module_list_functions();
8084
} else if (argc == 2 && !strcmp(argv[1], "--module-list-globals")) {
8185
return llvm_module_list_globals();
86+
} else if (argc == 2 && !strcmp(argv[1], "--module-get-producer-string")) {
87+
return llvm_module_get_producer_string();
8288
} else if (argc == 2 && !strcmp(argv[1], "--targets-list")) {
8389
return llvm_targets_list();
8490
} else if (argc == 2 && !strcmp(argv[1], "--object-list-sections")) {

llvm/tools/llvm-c-test/module.c

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
|* *|
88
|*===----------------------------------------------------------------------===*|
99
|* *|
10-
|* This file implements the --module-dump, --module-list-functions and *|
11-
|* --module-list-globals commands in llvm-c-test. *|
10+
|* This file implements the module-related commands in llvm-c-test. *|
1211
|* *|
1312
\*===----------------------------------------------------------------------===*/
1413

@@ -135,3 +134,36 @@ int llvm_module_list_globals(void) {
135134

136135
return 0;
137136
}
137+
138+
int llvm_module_get_producer_string(void) {
139+
LLVMMemoryBufferRef MB;
140+
char *Msg = NULL;
141+
if (LLVMCreateMemoryBufferWithSTDIN(&MB, &Msg)) {
142+
fprintf(stderr, "Error reading file: %s\n", Msg);
143+
LLVMDisposeMessage(Msg);
144+
return 1;
145+
}
146+
147+
char *Producer = NULL;
148+
char *Err = NULL;
149+
LLVMBool Ret = LLVMGetBitcodeProducerString(MB, &Producer, &Err);
150+
LLVMDisposeMemoryBuffer(MB);
151+
152+
if (Ret || Err) {
153+
fprintf(stderr, "Error reading bitcode: %s\n", Err ? Err : "unknown");
154+
if (Err)
155+
LLVMDisposeMessage(Err);
156+
if (Producer)
157+
LLVMDisposeMessage(Producer);
158+
return 1;
159+
}
160+
161+
if (Producer) {
162+
printf("%s\n", Producer);
163+
LLVMDisposeMessage(Producer);
164+
} else {
165+
fprintf(stderr, "Bitcode has an empty producer");
166+
}
167+
168+
return 0;
169+
}

0 commit comments

Comments
 (0)