Index: experimental/visual_studio_plugin/third_party/breakpad/common/stabs_reader_unittest.cc |
diff --git a/experimental/visual_studio_plugin/third_party/breakpad/common/stabs_reader_unittest.cc b/experimental/visual_studio_plugin/third_party/breakpad/common/stabs_reader_unittest.cc |
deleted file mode 100644 |
index a22d9d0e5e12505d2435d04d2f0173185354fbc8..0000000000000000000000000000000000000000 |
--- a/experimental/visual_studio_plugin/third_party/breakpad/common/stabs_reader_unittest.cc |
+++ /dev/null |
@@ -1,685 +0,0 @@ |
-// Copyright (c) 2010 Google Inc. |
-// All rights reserved. |
-// |
-// Redistribution and use in source and binary forms, with or without |
-// modification, are permitted provided that the following conditions are |
-// met: |
-// |
-// * Redistributions of source code must retain the above copyright |
-// notice, this list of conditions and the following disclaimer. |
-// * Redistributions in binary form must reproduce the above |
-// copyright notice, this list of conditions and the following disclaimer |
-// in the documentation and/or other materials provided with the |
-// distribution. |
-// * Neither the name of Google Inc. nor the names of its |
-// contributors may be used to endorse or promote products derived from |
-// this software without specific prior written permission. |
-// |
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
- |
-// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> |
- |
-// stabs_reader_unittest.cc: Unit tests for google_breakpad::StabsReader. |
- |
-#include <a.out.h> |
-#include <cassert> |
-#include <cerrno> |
-#include <cstdarg> |
-#include <cstdlib> |
-#include <cstring> |
-#include <fstream> |
-#include <iomanip> |
-#include <iostream> |
-#include <map> |
-#include <sstream> |
-#include <stab.h> |
- |
-#include "breakpad_googletest_includes.h" |
-#include "common/stabs_reader.h" |
- |
-using std::istream; |
-using std::istringstream; |
-using std::map; |
-using std::ostream; |
-using std::ostringstream; |
-using std::string; |
- |
-using ::testing::_; |
-using ::testing::Eq; |
-using ::testing::InSequence; |
-using ::testing::Return; |
-using ::testing::Sequence; |
-using ::testing::StrEq; |
- |
-using google_breakpad::StabsHandler; |
-using google_breakpad::StabsReader; |
- |
-namespace { |
- |
-// Mock stabs file parser |
-// |
-// In order to test StabsReader, we parse a human-readable input file |
-// describing STABS entries into in-memory .stab and .stabstr |
-// sections, and then pass those to StabsReader to look at. The |
-// human-readable file is called a "mock stabs file". |
-// |
-// Except for compilation unit boundary lines (described below), each |
-// line of a mock stabs file should have the following form: |
-// |
-// TYPE OTHER DESC VALUE NAME |
-// |
-// where all data is Latin-1 bytes and fields are separated by single |
-// space characters, except for NAME, which may contain spaces and |
-// continues to the end of the line. The fields have the following |
-// meanings: |
-// |
-// - TYPE: the name of the stabs symbol type; like SO or FUN. These are |
-// the names from /usr/include/bits/stab.def, without the leading N_. |
-// |
-// - OTHER, DESC, VALUE: numeric values for the n_other, n_desc, and |
-// n_value fields of the stab. These can be decimal or hex, |
-// using C++ notation (10, 0x10) |
-// |
-// - NAME: textual data for the entry. STABS packs all kinds of |
-// interesting data into entries' NAME fields, so calling it a NAME |
-// is misleading, but that's how it is. For SO, this may be a |
-// filename; for FUN, this is the function name, plus type data; and |
-// so on. |
-// |
-// A compilation unit boundary line has the form: |
-// |
-// cu-boundary FILENAME |
- |
-// I don't know if the whole parser/handler pattern is really worth |
-// the bureaucracy in this case. But just writing it out as |
-// old-fashioned functions wasn't astonishingly clear either, so it |
-// seemed worth a try. |
- |
-// A handler class for mock stabs data. |
-class MockStabsHandler { |
- public: |
- MockStabsHandler() { } |
- virtual ~MockStabsHandler() { } |
- // The mock stabs parser calls this member function for each entry |
- // it parses, passing it the contents of the entry. If this function |
- // returns true, the parser continues; if it returns false, the parser |
- // stops, and its Process member function returns false. |
- virtual bool Entry(enum __stab_debug_code type, char other, short desc, |
- unsigned long value, const string &name) { return true; } |
- // Report a compilation unit boundary whose filename is FILENAME. As |
- // for the Entry function, this should return true to continue |
- // parsing, or false to stop processing. |
- virtual bool CUBoundary(const string &filename) { return true; } |
- |
- // Report an error in parsing the mock stabs data. If this returns true, |
- // the parser continues; if it returns false, the parser stops and |
- // its Process member function returns false. |
- virtual bool Error(const char *format, ...) = 0; |
-}; |
- |
-// A class for parsing mock stabs files. |
-class MockStabsParser { |
- public: |
- // Create a parser reading input from STREAM and passing data to HANDLER. |
- // Use FILENAME when reporting errors. |
- MockStabsParser(const string &filename, istream *stream, |
- MockStabsHandler *handler); |
- // Parse data from the STREAM, invoking HANDLER->Entry for each |
- // entry we get. Return true if we parsed all the data succesfully, |
- // or false if we stopped early because Entry returned false, or if |
- // there were any errors during parsing. |
- bool Process(); |
- private: |
- // A type for maps from stab type names ("SO", "SLINE", etc.) to |
- // n_type values. |
- typedef map<string, unsigned char> StabTypeNameTable; |
- |
- // Initialize the table mapping STAB type names to n_type values. |
- void InitializeTypeNames(); |
- |
- // Parse LINE, one line of input from a mock stabs file, and pass |
- // its contents to handler_->Entry and return the boolean value that |
- // returns. If we encounter an error parsing the line, report it |
- // using handler->Error. |
- bool ParseLine(const string &line); |
- |
- const string &filename_; |
- istream *stream_; |
- MockStabsHandler *handler_; |
- int line_number_; |
- StabTypeNameTable type_names_; |
-}; |
- |
-MockStabsParser::MockStabsParser(const string &filename, istream *stream, |
- MockStabsHandler *handler): |
- filename_(filename), stream_(stream), handler_(handler), |
- line_number_(0) { |
- InitializeTypeNames(); |
-} |
- |
-bool MockStabsParser::Process() { |
- // Iterate once per line, including a line at EOF without a |
- // terminating newline. |
- for(;;) { |
- string line; |
- getline(*stream_, line, '\n'); |
- if (line.empty() && stream_->eof()) |
- break; |
- line_number_++; |
- if (! ParseLine(line)) |
- return false; |
- } |
- return true; |
-} |
- |
-void MockStabsParser::InitializeTypeNames() { |
- // On GLIBC-based systems, <bits/stab.def> is a file containing a |
- // call to an unspecified macro __define_stab for each stab type. |
- // <stab.h> uses it to define the __stab_debug_code enum type. We |
- // use it here to initialize our mapping from type names to enum |
- // values. |
- // |
- // This isn't portable to non-GLIBC systems. Feel free to just |
- // hard-code the values if this becomes a problem. |
-# define __define_stab(name, code, str) type_names_[string(str)] = code; |
-# include <bits/stab.def> |
-# undef __define_stab |
-} |
- |
-bool MockStabsParser::ParseLine(const string &line) { |
- istringstream linestream(line); |
- // Allow "0x" prefix for hex, and so on. |
- linestream.unsetf(istringstream::basefield); |
- // Parse and validate the stabs type. |
- string typeName; |
- linestream >> typeName; |
- if (typeName == "cu-boundary") { |
- if (linestream.peek() == ' ') |
- linestream.get(); |
- string filename; |
- getline(linestream, filename, '\n'); |
- return handler_->CUBoundary(filename); |
- } else { |
- StabTypeNameTable::const_iterator typeIt = type_names_.find(typeName); |
- if (typeIt == type_names_.end()) |
- return handler_->Error("%s:%d: unrecognized stab type: %s\n", |
- filename_.c_str(), line_number_, typeName.c_str()); |
- // These are int, not char and unsigned char, to ensure they're parsed |
- // as decimal numbers, not characters. |
- int otherInt, descInt; |
- unsigned long value; |
- linestream >> otherInt >> descInt >> value; |
- if (linestream.fail()) |
- return handler_->Error("%s:%d: malformed mock stabs input line\n", |
- filename_.c_str(), line_number_); |
- if (linestream.peek() == ' ') |
- linestream.get(); |
- string name; |
- getline(linestream, name, '\n'); |
- return handler_->Entry(static_cast<__stab_debug_code>(typeIt->second), |
- otherInt, descInt, value, name); |
- } |
-} |
- |
-// A class for constructing .stab sections. |
-// |
-// A .stab section is an array of struct nlist entries. These |
-// entries' n_un.n_strx fields are indices into an accompanying |
-// .stabstr section. |
-class StabSection { |
- public: |
- StabSection(): used_(0), size_(1) { |
- entries_ = (struct nlist *) malloc(sizeof(*entries_) * size_); |
- } |
- ~StabSection() { free(entries_); } |
- |
- // Append a new 'struct nlist' entry to the end of the section, and |
- // return a pointer to it. This pointer is valid until the next |
- // call to Append. The caller should initialize the returned entry |
- // as needed. |
- struct nlist *Append(); |
- // Set the first entry's n_desc field to COUNT, and set its n_value field |
- // to STRING_SIZE. |
- void SetHeader(short count, unsigned long string_size); |
- // Set SECTION to the contents of a .stab section holding the |
- // accumulated list of entries added with Append. |
- void GetSection(string *section); |
- // Clear the array, and prepare this StabSection to accumulate a fresh |
- // set of entries. |
- void Clear(); |
- |
- private: |
- // The array of stabs entries, |
- struct nlist *entries_; |
- // The number of elements of entries_ that are used, and the allocated size |
- // of the array. |
- size_t used_, size_; |
-}; |
- |
-struct nlist *StabSection::Append() { |
- if (used_ == size_) { |
- size_ *= 2; |
- entries_ = (struct nlist *) realloc(entries_, sizeof(*entries_) * size_); |
- } |
- assert(used_ < size_); |
- return &entries_[used_++]; |
-} |
- |
-void StabSection::SetHeader(short count, unsigned long string_size) { |
- assert(used_ >= 1); |
- entries_[0].n_desc = count; |
- entries_[0].n_value = string_size; |
-} |
- |
-void StabSection::GetSection(string *section) { |
- section->assign(reinterpret_cast<char *>(entries_), |
- sizeof(*entries_) * used_); |
-} |
- |
-void StabSection::Clear() { |
- used_ = 0; |
- size_ = 1; |
- entries_ = (struct nlist *) realloc(entries_, sizeof(*entries_) * size_); |
-} |
- |
-// A class for building .stabstr sections. |
-// |
-// A .stabstr section is an array of characters containing a bunch of |
-// null-terminated strings. A string is identified by the index of |
-// its initial character in the array. The array always starts with a |
-// null byte, so that an index of zero refers to the empty string. |
-// |
-// This implementation also ensures that if two strings are equal, we |
-// assign them the same indices; most linkers do this, and some |
-// clients may rely upon it. (Note that this is not quite the same as |
-// ensuring that a string only appears once in the section; you could |
-// share space when one string is a suffix of another, but we don't.) |
-class StabstrSection { |
- public: |
- StabstrSection(): next_byte_(1) { string_indices_[""] = 0; } |
- // Ensure STR is present in the string section, and return its index. |
- size_t Insert(const string &str); |
- // Set SECTION to the contents of a .stabstr section in which the |
- // strings passed to Insert appear at the indices we promised. |
- void GetSection(string *section); |
- // Clear the contents of this StabstrSection, and prepare it to |
- // accumulate a new set of strings. |
- void Clear(); |
- private: |
- // Maps from strings to .stabstr indices and back. |
- typedef map<string, size_t> StringToIndex; |
- typedef map<size_t, const string *> IndexToString; |
- |
- // A map from strings to the indices we've assigned them. |
- StringToIndex string_indices_; |
- |
- // The next unused byte in the section. The next string we add |
- // will get this index. |
- size_t next_byte_; |
-}; |
- |
-size_t StabstrSection::Insert(const string &str) { |
- StringToIndex::iterator it = string_indices_.find(str); |
- size_t index; |
- if (it != string_indices_.end()) { |
- index = it->second; |
- } else { |
- // This is the first time we've seen STR; add it to the table. |
- string_indices_[str] = next_byte_; |
- index = next_byte_; |
- next_byte_ += str.size() + 1; |
- } |
- return index; |
-} |
- |
-void StabstrSection::GetSection(string *section) { |
- // First we have to invert the map. |
- IndexToString byIndex; |
- for (StringToIndex::const_iterator it = string_indices_.begin(); |
- it != string_indices_.end(); it++) |
- byIndex[it->second] = &it->first; |
- // Now we build the .stabstr section. |
- section->clear(); |
- for (IndexToString::const_iterator it = byIndex.begin(); |
- it != byIndex.end(); it++) { |
- // Make sure we're actually assigning it the index we claim to be. |
- assert(it->first == section->size()); |
- *section += *(it->second); |
- *section += '\0'; |
- } |
-} |
- |
-void StabstrSection::Clear() { |
- string_indices_.clear(); |
- string_indices_[""] = 0; |
- next_byte_ = 1; |
-} |
- |
-// A mock stabs parser handler class that builds .stab and .stabstr |
-// sections. |
-class StabsSectionsBuilder: public MockStabsHandler { |
- public: |
- // Construct a handler that will receive data from a MockStabsParser |
- // and construct .stab and .stabstr sections. FILENAME should be |
- // the name of the mock stabs input file; we use it in error |
- // messages. |
- StabsSectionsBuilder(const string &filename) |
- : filename_(filename), error_count_(0), has_header_(false), |
- entry_count_(0) { } |
- |
- // Overridden virtual member functions. |
- bool Entry(enum __stab_debug_code type, char other, short desc, |
- unsigned long value, const string &name); |
- bool CUBoundary(const string &filename); |
- bool Error(const char *format, ...); |
- |
- // Set SECTION to the contents of a .stab or .stabstr section |
- // reflecting the entries that have been passed to us via Entry. |
- void GetStab(string *section); |
- void GetStabstr(string *section); |
- |
- private: |
- // Finish a compilation unit. If there are any entries accumulated in |
- // stab_ and stabstr_, add them as a new compilation unit to |
- // finished_cu_stabs_ and finished_cu_stabstr_, and then clear stab_ and |
- // stabstr_. |
- void FinishCU(); |
- |
- const string &filename_; // input filename, for error messages |
- int error_count_; // number of errors we've seen so far |
- |
- // The following members accumulate the contents of a single compilation |
- // unit, possibly headed by an N_UNDF stab. |
- bool has_header_; // true if we have an N_UNDF header |
- int entry_count_; // the number of entries we've seen |
- StabSection stab_; // 'struct nlist' entries |
- StabstrSection stabstr_; // and the strings they love |
- |
- // Accumulated .stab and .stabstr content for all compilation units. |
- string finished_cu_stab_, finished_cu_stabstr_; |
-}; |
- |
-bool StabsSectionsBuilder::Entry(enum __stab_debug_code type, char other, |
- short desc, unsigned long value, |
- const string &name) { |
- struct nlist *entry = stab_.Append(); |
- entry->n_type = type; |
- entry->n_other = other; |
- entry->n_desc = desc; |
- entry->n_value = value; |
- entry->n_un.n_strx = stabstr_.Insert(name); |
- entry_count_++; |
- return true; |
-} |
- |
-bool StabsSectionsBuilder::CUBoundary(const string &filename) { |
- FinishCU(); |
- // Add a header for the compilation unit. |
- assert(!has_header_); |
- assert(entry_count_ == 0); |
- struct nlist *entry = stab_.Append(); |
- entry->n_type = N_UNDF; |
- entry->n_other = 0; |
- entry->n_desc = 0; // will be set to number of entries |
- entry->n_value = 0; // will be set to size of .stabstr data |
- entry->n_un.n_strx = stabstr_.Insert(filename); |
- has_header_ = true; |
- // The N_UNDF header isn't included in the symbol count, so we |
- // shouldn't bump entry_count_ here. |
- return true; |
-} |
- |
-void StabsSectionsBuilder::FinishCU() { |
- if (entry_count_ > 0) { |
- // Get the strings first, so we can record their size in the header. |
- string stabstr; |
- stabstr_.GetSection(&stabstr); |
- finished_cu_stabstr_ += stabstr; |
- |
- // Initialize our header, if we have one, and extract the .stab data. |
- if (has_header_) |
- stab_.SetHeader(entry_count_, stabstr.size()); |
- string stab; |
- stab_.GetSection(&stab); |
- finished_cu_stab_ += stab; |
- } |
- |
- stab_.Clear(); |
- stabstr_.Clear(); |
- has_header_ = false; |
- entry_count_ = 0; |
-} |
- |
-bool StabsSectionsBuilder::Error(const char *format, ...) { |
- va_list args; |
- va_start(args, format); |
- vfprintf(stderr, format, args); |
- va_end(args); |
- error_count_++; |
- if (error_count_ >= 20) { |
- fprintf(stderr, |
- "%s: lots of errors; is this really a mock stabs file?\n", |
- filename_.c_str()); |
- return false; |
- } |
- return true; |
-} |
- |
-void StabsSectionsBuilder::GetStab(string *section) { |
- FinishCU(); |
- *section = finished_cu_stab_; |
-} |
- |
-void StabsSectionsBuilder::GetStabstr(string *section) { |
- FinishCU(); |
- *section = finished_cu_stabstr_; |
-} |
- |
-class MockStabsReaderHandler: public StabsHandler { |
- public: |
- MOCK_METHOD3(StartCompilationUnit, |
- bool(const char *, uint64_t, const char *)); |
- MOCK_METHOD1(EndCompilationUnit, bool(uint64_t)); |
- MOCK_METHOD2(StartFunction, bool(const std::string &, uint64_t)); |
- MOCK_METHOD1(EndFunction, bool(uint64_t)); |
- MOCK_METHOD3(Line, bool(uint64_t, const char *, int)); |
- void Warning(const char *format, ...) { MockWarning(format); } |
- MOCK_METHOD1(MockWarning, void(const char *)); |
-}; |
- |
-// Create a StabsReader to parse the mock stabs data in INPUT_FILE, |
-// passing the parsed information to HANDLER. If all goes well, return |
-// the result of calling the reader's Process member function. |
-// Otherwise, return false. INPUT_FILE should be relative to the top |
-// of the source tree. |
-static bool ApplyHandlerToMockStabsData(StabsHandler *handler, |
- const string &input_file) { |
- string full_input_file |
- = string(getenv("srcdir") ? getenv("srcdir") : ".") + "/" + input_file; |
- |
- // Open the input file. |
- std::ifstream stream(full_input_file.c_str()); |
- if (stream.fail()) { |
- fprintf(stderr, "error opening mock stabs input file %s: %s\n", |
- full_input_file.c_str(), strerror(errno)); |
- return false; |
- } |
- |
- // Parse the mock stabs data, and produce stabs sections to use as |
- // test input to the reader. |
- StabsSectionsBuilder builder(full_input_file); |
- MockStabsParser mock_parser(full_input_file, &stream, &builder); |
- if (!mock_parser.Process()) |
- return false; |
- string stab, stabstr; |
- builder.GetStab(&stab); |
- builder.GetStabstr(&stabstr); |
- |
- // Run the parser on the test input, passing whatever we find to HANDLER. |
- StabsReader reader( |
- reinterpret_cast<const uint8_t *>(stab.data()), stab.size(), |
- reinterpret_cast<const uint8_t *>(stabstr.data()), stabstr.size(), |
- handler); |
- return reader.Process(); |
-} |
- |
-TEST(StabsReader, MockStabsInput) { |
- MockStabsReaderHandler mock_handler; |
- |
- { |
- InSequence s; |
- |
- EXPECT_CALL(mock_handler, StartCompilationUnit(StrEq("file1.c"), |
- 0x42, StrEq("builddir1/"))) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, StartFunction(StrEq("fun1"), 0x62)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, Line(0xe4, StrEq("file1.c"), 91)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, Line(0x164, StrEq("header.h"), 111)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, EndFunction(0x112)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, StartFunction(StrEq("fun2"), 0x112)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, Line(0x234, StrEq("header.h"), 131)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, Line(0x254, StrEq("file1.c"), 151)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, EndFunction(0x152)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, EndCompilationUnit(0x152)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, StartCompilationUnit(StrEq("file3.c"), |
- 0x182, NULL)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, EndCompilationUnit(0x192)) |
- .WillOnce(Return(true)); |
- } |
- |
- ASSERT_TRUE(ApplyHandlerToMockStabsData( |
- &mock_handler, |
- "common/testdata/stabs_reader_unittest.input1")); |
-} |
- |
-TEST(StabsReader, AbruptCU) { |
- MockStabsReaderHandler mock_handler; |
- |
- { |
- InSequence s; |
- |
- EXPECT_CALL(mock_handler, |
- StartCompilationUnit(StrEq("file2-1.c"), 0x12, NULL)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, EndCompilationUnit(NULL)) |
- .WillOnce(Return(true)); |
- } |
- |
- ASSERT_TRUE(ApplyHandlerToMockStabsData( |
- &mock_handler, |
- "common/testdata/stabs_reader_unittest.input2")); |
-} |
- |
-TEST(StabsReader, AbruptFunction) { |
- MockStabsReaderHandler mock_handler; |
- |
- { |
- InSequence s; |
- |
- EXPECT_CALL(mock_handler, |
- StartCompilationUnit(StrEq("file3-1.c"), 0x12, NULL)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, StartFunction(StrEq("fun3_1"), 0x22)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, EndFunction(NULL)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, EndCompilationUnit(NULL)) |
- .WillOnce(Return(true)); |
- } |
- |
- ASSERT_TRUE(ApplyHandlerToMockStabsData( |
- &mock_handler, |
- "common/testdata/stabs_reader_unittest.input3")); |
-} |
- |
-TEST(StabsReader, NoCU) { |
- MockStabsReaderHandler mock_handler; |
- |
- EXPECT_CALL(mock_handler, StartCompilationUnit(_, _, _)) |
- .Times(0); |
- EXPECT_CALL(mock_handler, StartFunction(_, _)) |
- .Times(0); |
- |
- ASSERT_TRUE(ApplyHandlerToMockStabsData( |
- &mock_handler, |
- "common/testdata/stabs_reader_unittest.input4")); |
- |
-} |
- |
-TEST(StabsReader, NoCUEnd) { |
- MockStabsReaderHandler mock_handler; |
- |
- { |
- InSequence s; |
- |
- EXPECT_CALL(mock_handler, |
- StartCompilationUnit(StrEq("file5-1.c"), 0x12, NULL)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, EndCompilationUnit(NULL)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, |
- StartCompilationUnit(StrEq("file5-2.c"), 0x22, NULL)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, EndCompilationUnit(NULL)) |
- .WillOnce(Return(true)); |
- } |
- |
- ASSERT_TRUE(ApplyHandlerToMockStabsData( |
- &mock_handler, |
- "common/testdata/stabs_reader_unittest.input5")); |
- |
-} |
- |
-TEST(StabsReader, MultipleCUs) { |
- MockStabsReaderHandler mock_handler; |
- |
- { |
- InSequence s; |
- EXPECT_CALL(mock_handler, |
- StartCompilationUnit(StrEq("antimony"), 0x12, NULL)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, StartFunction(Eq("arsenic"), 0x22)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, EndFunction(0x32)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, EndCompilationUnit(0x32)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, |
- StartCompilationUnit(StrEq("aluminum"), 0x42, NULL)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, StartFunction(Eq("selenium"), 0x52)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, EndFunction(0x62)) |
- .WillOnce(Return(true)); |
- EXPECT_CALL(mock_handler, EndCompilationUnit(0x62)) |
- .WillOnce(Return(true)); |
- } |
- |
- ASSERT_TRUE(ApplyHandlerToMockStabsData( |
- &mock_handler, |
- "common/testdata/stabs_reader_unittest.input6")); |
-} |
- |
-// name duplication |
- |
-} // anonymous namespace |