def test_union(self): src = """ struct C{ union U{ int a; }s; }; """ parser = CXXParser("./test.cpp", [("./test.cpp", src)]) result = parser.parse() # U in C C = result.g.classes['C'] self.assertIn("s", C.variables) self.assertIn('U', C.classes) self.assertNotIn('a', C.variables) # a in s U = C.classes['U'] self.assertIn('a', U.variables) a = U.variables['a'] # limits self.assertEqual(1, len(C.classes)) self.assertEqual(1, len(C.variables)) self.assertEqual(0, len(U.classes)) self.assertEqual(1, len(U.variables)) # objects self.assertEqual(C, result.objects['C']) self.assertEqual(U, result.objects['C::U']) self.assertEqual(a, result.objects['C::U::a'])
def test_union_anonymous_scoped(self): src = """ struct C{ union { int a; }s; }; """ parser = CXXParser("./test.cpp", [("./test.cpp", src)]) result = parser.parse() # s in C C = result.g.classes['C'] self.assertIn("s", C.variables) self.assertNotIn("a", C.variables) # a in s typeof_s = C.classes['decltype(s)'] self.assertIsInstance(typeof_s, AnonymousUnion) self.assertIn('a', typeof_s.variables) a = typeof_s.variables['a'] # limits self.assertEqual(1, len(C.classes)) # one anonymous class self.assertEqual(1, len(C.variables)) self.assertEqual(0, len(typeof_s.classes)) self.assertEqual(1, len(typeof_s.variables)) # objects self.assertEqual(C, result.objects['C']) self.assertEqual(typeof_s, result.objects['decltype(C::s)']) self.assertEqual(a, result.objects['decltype(C::s)::a'])
def test_stl_optional(self): src = """ #include <optional> std::optional<int> v = 1; """ parser = CXXParser("./test.cpp", [("./test.cpp", src)]) result = parser.parse() v = result.g.variables['v'] self.assertEqual("std::optional<int>", v.type)
def test_variable_short_brief_comment(self): src = """ //! ss int short_ = 1; """ parser = CXXParser("./test.cpp", [("./test.cpp", src)]) result = parser.parse() short = result.g.variables['short_'] self.assertEqual("ss", short.brief_comment)
def test_global_const(self): src = """ const int a = 1; """ parser = CXXParser("./test.cpp", [ ("./test.cpp", src) ]) result = parser.parse() a = result.g.variables['a'] self.assertTrue(a.const)
def test_static_const(self): src = """ static constexpr int a = 2; """ parser = CXXParser("./test.cpp", [ ("./test.cpp", src) ]) result = parser.parse() a = result.g.variables['a'] self.assertTrue(a.const)
def test_pointer_to_const(self): src = """ const char *a = ""; """ parser = CXXParser("./test.cpp", [ ("./test.cpp", src) ]) result = parser.parse() a = result.g.variables['a'] self.assertFalse(a.const)
def test_const_pointer(self): src = """ char * const a = ""; """ parser = CXXParser("./test.cpp", [ ("./test.cpp", src) ]) result = parser.parse() a = result.g.variables['a'] self.assertTrue(is_const_type(a.type)) self.assertTrue(a.const)
def test_variable_long_brief_comment(self): src = """ /*! * abcd */ int long_ = 1; """ parser = CXXParser("./test.cpp", [("./test.cpp", src)]) result = parser.parse() long = result.g.variables['long_'] self.assertEqual("abcd", long.brief_comment)
def test_const_multiple_level_pointer(self): src = """ #define N 0 char ** const a = N; """ parser = CXXParser("./test.cpp", [ ("./test.cpp", src) ]) result = parser.parse() a = result.g.variables['a'] self.assertTrue(is_const_type(a.type)) self.assertTrue(a.const)
def test_in_scope_type(self): src = """ namespace ns1{ using int32 = int; int32 a = 1; }; """ parser = CXXParser("./test.cpp", [("./test.cpp", src)]) result = parser.parse() ns1 = result.g.namespaces['ns1'] self.assertIn("a", ns1.variables) self.assertEqual("ns1::int32", ns1.variables['a'].type)
def test_nested_const(self): src = """ struct S{ const int a = 1; }; """ parser = CXXParser("./test.cpp", [ ("./test.cpp", src) ]) result = parser.parse() s = result.g.classes['S'] a = s.variables['a'] self.assertTrue(is_const_type(a.type)) self.assertTrue(a.const)
def test_undef(self): src = """ #define A 1234 #undef A """ extra_options = CXXParserExtraOptions() extra_options.arch = Arch.X86 unsaved_files = [("./test.cpp", src)] parser = CXXParser( "./test.cpp", unsaved_files, extra_options=extra_options, ) result = parser.parse() self.assertNotIn('A', result.macros)
def test_value(self): src = """ #define A 1234 #undef A #define A 123 int a = A; """ extra_options = CXXParserExtraOptions() extra_options.arch = Arch.X86 unsaved_files = [("./test.cpp", src)] parser = CXXParser( "./test.cpp", unsaved_files, extra_options=extra_options, ) result = parser.parse() self.assertEqual('123', result.macros['A'].definition) self.assertEqual(123, result.g.variables['a'].value)
def test_cross_scope_typedef(self): src = """ namespace ns1{ using int32 = int; }; namespace ns2{ using int32 = ns1::int32; } """ parser = CXXParser("./test.cpp", [("./test.cpp", src)]) result = parser.parse() ns1 = result.g.namespaces['ns1'] self.assertIn("int32", ns1.typedefs) self.assertEqual("int", ns1.typedefs['int32'].target) ns2 = result.g.namespaces['ns2'] self.assertIn("int32", ns2.typedefs) self.assertEqual("::ns1::int32", ns2.typedefs['int32'].target)
def test_using_type(self): src = """ namespace ns1{ class A{}; }; namespace ns2{ using ns1::A; } """ parser = CXXParser("./test.cpp", [("./test.cpp", src)]) result = parser.parse() self.assertIn("ns1", result.g.namespaces) ns1 = result.g.namespaces['ns1'] self.assertIn("A", ns1.classes) self.assertIn("ns2", result.g.namespaces) ns2 = result.g.namespaces['ns2'] self.assertIn("A", ns2.classes)
def test_nested_namespace(self): src = """ namespace outer{ namespace inner{ class Inner1{}; } class Outer1{}; int namespace_func(); }; """ parser = CXXParser("./test.cpp", [("./test.cpp", src)]) result = parser.parse() self.assertIn("outer", result.g.namespaces) outer = result.g.namespaces['outer'] self.assertIn("Outer1", outer.classes) self.assertIn("inner", outer.namespaces) inner = outer.namespaces['inner'] self.assertIn("Inner1", inner.classes)
def test_32(self): src = """ #ifdef _WIN64 const int a = 64; #else const int a = 32; #endif """ extra_options = CXXParserExtraOptions() extra_options.arch = Arch.X86 unsaved_files = [ ("./test.cpp", src) ] parser = CXXParser("./test.cpp", unsaved_files, extra_options=extra_options, ) result = parser.parse() a = result.g.variables['a'] self.assertEqual(int, type(a.value)) self.assertEqual(32, a.value)
def test_partial_namespace(self): src1 = """ namespace ns1{ class A{}; }; """ src2 = """ namespace ns1{ class B{}; }; """ parser = CXXParser("src.h", [ ("src.h", '#include "1.h"\n#include "2.h"'), ("./1.h", src1), ("./2.h", src2), ]) result = parser.parse() self.assertIn("ns1", result.g.namespaces) ns1 = result.g.namespaces['ns1'] self.assertIn("A", ns1.classes) self.assertIn("B", ns1.classes)
def test_union_anonymous_unscoped(self): src = """ struct C{ union { int a; }; }; """ parser = CXXParser("./test.cpp", [("./test.cpp", src)]) result = parser.parse() # a in C C = result.g.classes['C'] self.assertIn("a", C.variables) a = C.variables['a'] # limits self.assertEqual(0, len(C.classes)) self.assertEqual(1, len(C.variables)) # objects self.assertEqual(C, result.objects['C']) self.assertEqual(a, result.objects['C::a'])