From e3e5ccdbe3349f5456eabecb8f6abcd2c31c9df2 Mon Sep 17 00:00:00 2001 From: Brenden Blanco Date: Sun, 1 May 2016 21:29:08 -0700 Subject: [PATCH] Add clang support for nested struct/union as key field Clang was up until now not able to parse nested structs or unions as a field in the table key or leaf. Add support in the library side, as well as python support for the exported json description. --- src/cc/frontends/clang/b_frontend_action.cc | 6 ++++++ src/python/bcc/__init__.py | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/cc/frontends/clang/b_frontend_action.cc b/src/cc/frontends/clang/b_frontend_action.cc index 852abc0..17ead62 100644 --- a/src/cc/frontends/clang/b_frontend_action.cc +++ b/src/cc/frontends/clang/b_frontend_action.cc @@ -67,6 +67,12 @@ bool BMapDeclVisitor::VisitRecordDecl(RecordDecl *D) { result_ += D->getName(); result_ += "\", ["; for (auto F : D->getDefinition()->fields()) { + if (F->isAnonymousStructOrUnion()) { + if (const RecordType *R = dyn_cast(F->getType())) + TraverseDecl(R->getDecl()); + result_ += ", "; + continue; + } result_ += "["; TraverseDecl(F); if (const ConstantArrayType *T = dyn_cast(F->getType())) diff --git a/src/python/bcc/__init__.py b/src/python/bcc/__init__.py index 5a393c1..55bbbaa 100644 --- a/src/python/bcc/__init__.py +++ b/src/python/bcc/__init__.py @@ -250,6 +250,7 @@ class BPF(object): def _decode_table_type(desc): if isinstance(desc, basestring): return BPF.str2ctype[desc] + anon = [] fields = [] for t in desc[1]: if len(t) == 2: @@ -257,8 +258,17 @@ class BPF(object): elif len(t) == 3: if isinstance(t[2], list): fields.append((t[0], BPF._decode_table_type(t[1]) * t[2][0])) - else: + elif isinstance(t[2], int): fields.append((t[0], BPF._decode_table_type(t[1]), t[2])) + elif isinstance(t[2], basestring) and ( + t[2] == u"union" or t[2] == u"struct"): + name = t[0] + if name == "": + name = "__anon%d" % len(anon) + anon.append(name) + fields.append((name, BPF._decode_table_type(t))) + else: + raise Exception("Failed to decode type %s" % str(t)) else: raise Exception("Failed to decode type %s" % str(t)) base = ct.Structure @@ -267,7 +277,8 @@ class BPF(object): base = ct.Union elif desc[2] == u"struct": base = ct.Structure - cls = type(str(desc[0]), (base,), dict(_fields_=fields)) + cls = type(str(desc[0]), (base,), dict(_anonymous_=anon, + _fields_=fields)) return cls def get_table(self, name, keytype=None, leaftype=None, reducer=None): -- 2.7.4