//
// Unit tests for functions in demangle.c.
+#include "utilities.h"
+
#include <iostream>
#include <fstream>
#include <string>
#include "googletest.h"
#include "config.h"
-DEFINE_bool(demangle_filter, false, "Run demangle_unittest in filter mode");
+#ifdef HAVE_LIB_GFLAGS
+#include <gflags/gflags.h>
+using namespace GFLAGS_NAMESPACE;
+#endif
+
+GLOG_DEFINE_bool(demangle_filter, false,
+ "Run demangle_unittest in filter mode");
using namespace std;
using namespace GOOGLE_NAMESPACE;
}
}
+#if defined(OS_WINDOWS)
+
+TEST(Demangle, Windows) {
+ EXPECT_STREQ(
+ "public: static void __cdecl Foo::func(int)",
+ DemangleIt("?func@Foo@@SAXH@Z"));
+ EXPECT_STREQ(
+ "public: static void __cdecl Foo::func(int)",
+ DemangleIt("@ILT+1105(?func@Foo@@SAXH@Z)"));
+ EXPECT_STREQ(
+ "int __cdecl foobarArray(int * const)",
+ DemangleIt("?foobarArray@@YAHQAH@Z"));
+}
+
+#else
+
// Test corner cases of bounary conditions.
TEST(Demangle, CornerCases) {
- char tmp[10];
- EXPECT_TRUE(Demangle("_Z6foobarv", tmp, sizeof(tmp)));
- // sizeof("foobar()") == 9
- EXPECT_STREQ("foobar()", tmp);
- EXPECT_TRUE(Demangle("_Z6foobarv", tmp, 9));
- EXPECT_STREQ("foobar()", tmp);
- EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 8)); // Not enough.
- EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 1));
- EXPECT_FALSE(Demangle("_Z6foobarv", tmp, 0));
- EXPECT_FALSE(Demangle("_Z6foobarv", NULL, 0)); // Should not cause SEGV.
+ const size_t size = 10;
+ char tmp[size] = { 0 };
+ const char *demangled = "foobar()";
+ const char *mangled = "_Z6foobarv";
+ EXPECT_TRUE(Demangle(mangled, tmp, sizeof(tmp)));
+ // sizeof("foobar()") == size - 1
+ EXPECT_STREQ(demangled, tmp);
+ EXPECT_TRUE(Demangle(mangled, tmp, size - 1));
+ EXPECT_STREQ(demangled, tmp);
+ EXPECT_FALSE(Demangle(mangled, tmp, size - 2)); // Not enough.
+ EXPECT_FALSE(Demangle(mangled, tmp, 1));
+ EXPECT_FALSE(Demangle(mangled, tmp, 0));
+ EXPECT_FALSE(Demangle(mangled, NULL, 0)); // Should not cause SEGV.
+}
+
+// Test handling of functions suffixed with .clone.N, which is used by GCC
+// 4.5.x, and .constprop.N and .isra.N, which are used by GCC 4.6.x. These
+// suffixes are used to indicate functions which have been cloned during
+// optimization. We ignore these suffixes.
+TEST(Demangle, Clones) {
+ char tmp[20];
+ EXPECT_TRUE(Demangle("_ZL3Foov", tmp, sizeof(tmp)));
+ EXPECT_STREQ("Foo()", tmp);
+ EXPECT_TRUE(Demangle("_ZL3Foov.clone.3", tmp, sizeof(tmp)));
+ EXPECT_STREQ("Foo()", tmp);
+ EXPECT_TRUE(Demangle("_ZL3Foov.constprop.80", tmp, sizeof(tmp)));
+ EXPECT_STREQ("Foo()", tmp);
+ EXPECT_TRUE(Demangle("_ZL3Foov.isra.18", tmp, sizeof(tmp)));
+ EXPECT_STREQ("Foo()", tmp);
+ EXPECT_TRUE(Demangle("_ZL3Foov.isra.2.constprop.18", tmp, sizeof(tmp)));
+ EXPECT_STREQ("Foo()", tmp);
+ // Invalid (truncated), should not demangle.
+ EXPECT_FALSE(Demangle("_ZL3Foov.clo", tmp, sizeof(tmp)));
+ // Invalid (.clone. not followed by number), should not demangle.
+ EXPECT_FALSE(Demangle("_ZL3Foov.clone.", tmp, sizeof(tmp)));
+ // Invalid (.clone. followed by non-number), should not demangle.
+ EXPECT_FALSE(Demangle("_ZL3Foov.clone.foo", tmp, sizeof(tmp)));
+ // Invalid (.constprop. not followed by number), should not demangle.
+ EXPECT_FALSE(Demangle("_ZL3Foov.isra.2.constprop.", tmp, sizeof(tmp)));
}
TEST(Demangle, FromFile) {
}
}
+#endif
+
int main(int argc, char **argv) {
#ifdef HAVE_LIB_GFLAGS
ParseCommandLineFlags(&argc, &argv, true);