[bcanalyzer] Recognize more stream types

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
This commit is contained in:
Brian Gesiak 2018-04-21 23:52:04 +00:00
parent 8a861286e9
commit 37f137831d
6 changed files with 61 additions and 19 deletions

View File

@ -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

View File

@ -0,0 +1 @@
CPCH

View File

@ -0,0 +1 @@
CP

View File

@ -0,0 +1 @@
DIAG

View File

@ -0,0 +1 @@
DIA

View File

@ -75,7 +75,9 @@ namespace {
/// CurStreamTypeType - A type for CurStreamType
enum CurStreamTypeType {
UnknownBitstream,
LLVMIRBitstream
LLVMIRBitstream,
ClangSerializedASTBitstream,
ClangSerializedDiagnosticsBitstream,
};
}
@ -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,
@ -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;
}
@ -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";