Skip to content

Commit

Permalink
[bcanalyzer] Recognize more stream types
Browse files Browse the repository at this point in the history
Summary:
`llvm-bcanalyzer` prints out the stream type of the file it is
analyzing. If the file begins with the LLVM IR magic number, it reports
a stream type of "LLVM IR". However, any other bitstream format is
reported as "unknown".

Add some checks for two other common bitstream formats: Clang AST
files, which begin with 'CPCH', and Clang serialized diagnostics, which
begin with 'DIAG'.

Test Plan: `check-llvm`

Reviewers: pcc, aprantl, mehdi_amini, davide, george.karpenkov, JDevlieghere

Reviewed By: JDevlieghere

Subscribers: JDevlieghere, bruno, davide, llvm-commits

Differential Revision: https://reviews.llvm.org/D41979

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@330529 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
modocache committed Apr 21, 2018
1 parent 8a86128 commit 37f1378
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 19 deletions.
12 changes: 12 additions & 0 deletions test/Bitcode/stream-types.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Tests that llvm-bcanalyzer recognizes the correct "stream type" for various
// common bitstream formats.

// RUN: llvm-bcanalyzer -dump %s.ast | FileCheck %s -check-prefix=CHECK-AST
// CHECK-AST: Stream type: Clang Serialized AST

// RUN: llvm-bcanalyzer -dump %s.dia | FileCheck %s -check-prefix=CHECK-DIAG
// CHECK-DIAG: Stream type: Clang Serialized Diagnostics

// RUN: not llvm-bcanalyzer -dump %s.ast.incomplete 2>&1 | FileCheck %s -check-prefix=CHECK-INCOMPLETE
// RUN: not llvm-bcanalyzer -dump %s.dia.incomplete 2>&1 | FileCheck %s -check-prefix=CHECK-INCOMPLETE
// CHECK-INCOMPLETE: Bitcode stream should be a multiple of 4 bytes in length
1 change: 1 addition & 0 deletions test/Bitcode/stream-types.c.ast
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CPCH
1 change: 1 addition & 0 deletions test/Bitcode/stream-types.c.ast.incomplete
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CP
1 change: 1 addition & 0 deletions test/Bitcode/stream-types.c.dia
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DIAG
1 change: 1 addition & 0 deletions test/Bitcode/stream-types.c.dia.incomplete
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DIA
64 changes: 45 additions & 19 deletions tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ namespace {
/// CurStreamTypeType - A type for CurStreamType
enum CurStreamTypeType {
UnknownBitstream,
LLVMIRBitstream
LLVMIRBitstream,
ClangSerializedASTBitstream,
ClangSerializedDiagnosticsBitstream,
};

}
Expand Down Expand Up @@ -746,6 +748,35 @@ static void PrintSize(uint64_t Bits) {
(double)Bits/8, (unsigned long)(Bits/32));
}

static CurStreamTypeType ReadSignature(BitstreamCursor &Stream) {
char Signature[6];
Signature[0] = Stream.Read(8);
Signature[1] = Stream.Read(8);

// Autodetect the file contents, if it is one we know.
if (Signature[0] == 'C' && Signature[1] == 'P') {
Signature[2] = Stream.Read(8);
Signature[3] = Stream.Read(8);
if (Signature[2] == 'C' && Signature[3] == 'H')
return ClangSerializedASTBitstream;
} else if (Signature[0] == 'D' && Signature[1] == 'I') {
Signature[2] = Stream.Read(8);
Signature[3] = Stream.Read(8);
if (Signature[2] == 'A' && Signature[3] == 'G')
return ClangSerializedDiagnosticsBitstream;
} else {
Signature[2] = Stream.Read(4);
Signature[3] = Stream.Read(4);
Signature[4] = Stream.Read(4);
Signature[5] = Stream.Read(4);
if (Signature[0] == 'B' && Signature[1] == 'C' &&
Signature[2] == 0x0 && Signature[3] == 0xC &&
Signature[4] == 0xE && Signature[5] == 0xD)
return LLVMIRBitstream;
}
return UnknownBitstream;
}

static bool openBitcodeFile(StringRef Path,
std::unique_ptr<MemoryBuffer> &MemBuf,
BitstreamCursor &Stream,
Expand Down Expand Up @@ -789,22 +820,7 @@ static bool openBitcodeFile(StringRef Path,
}

Stream = BitstreamCursor(ArrayRef<uint8_t>(BufPtr, EndBufPtr));

// Read the stream signature.
char Signature[6];
Signature[0] = Stream.Read(8);
Signature[1] = Stream.Read(8);
Signature[2] = Stream.Read(4);
Signature[3] = Stream.Read(4);
Signature[4] = Stream.Read(4);
Signature[5] = Stream.Read(4);

// Autodetect the file contents, if it is one we know.
CurStreamType = UnknownBitstream;
if (Signature[0] == 'B' && Signature[1] == 'C' &&
Signature[2] == 0x0 && Signature[3] == 0xC &&
Signature[4] == 0xE && Signature[5] == 0xD)
CurStreamType = LLVMIRBitstream;
CurStreamType = ReadSignature(Stream);

return false;
}
Expand Down Expand Up @@ -873,8 +889,18 @@ static int AnalyzeBitcode() {
outs() << "\n";
outs() << " Stream type: ";
switch (CurStreamType) {
case UnknownBitstream: outs() << "unknown\n"; break;
case LLVMIRBitstream: outs() << "LLVM IR\n"; break;
case UnknownBitstream:
outs() << "unknown\n";
break;
case LLVMIRBitstream:
outs() << "LLVM IR\n";
break;
case ClangSerializedASTBitstream:
outs() << "Clang Serialized AST\n";
break;
case ClangSerializedDiagnosticsBitstream:
outs() << "Clang Serialized Diagnostics\n";
break;
}
outs() << " # Toplevel Blocks: " << NumTopBlocks << "\n";
outs() << "\n";
Expand Down

0 comments on commit 37f1378

Please sign in to comment.