H.J. Hoogendorp wrote:
Dear Mr. Glek,

I am a student at the university of Groningen in the Netherlands. Currently I am working on my master's thesis on program slicing, with Alex Telea as my supervisor. An important part of this project concerns the construction of a call graph. For this, I am using the Elsa open-source parser. Mr. Telea tells me you have a great deal of knowledge and experience with the Elsa parser and it is on this that I would like to
ask you for your expertise.

For the most part, it is relatively straightforward to extract the information I'm looking for from the AST, which Elsa gives me. Extracting function definitions and most function calls is not a problem. However, the extraction of "implicit" function calls is giving me some problems. Let me elaborate where I encounter this problem, using three scenarios:
Hey Hessel,
I'm CCing our static analysis mailing list and oink's possibly dead mailing list. I suggest in the future you post to them(dev-static-analysis one is a sure bet, but there might be more knowledgeable lurkers on the oink-devel one). Elsa provides multiple views of the ast. I think you want the elaborated AST and you must be looking at the wrong one. I think that implies using the LoweredASTVisitor(it vists all of the AST nodes I expect to be visited, unlike the default visitors, not completely sure why). I suggest you download pork(http://developer.mozilla.org/en/Pork) and use the staticprint tool to examine the AST. It'll save you a lot of debugging time. In this case ./staticprint -fo-print-elaborated-ast yourtestcase.cc will show you the implicit constructors/destructors you want.
I'm attaching output from running staticprint on the first testcase.

Cheers,
Taras


SCENARIO 1 - Ctor & dtor call on class instantiation
====================================================

class T;        // Somewhere, a class T is defined.

void f()
{
// Here, the default ctor of T is called. Then, at the end of the scope of f, // T's destructor is called. However, these calls (ctor & dtor) cannot be found by // a "normal" tree traversal using an ASTVisitor. At least, I could not find them.
    T t;
}

=== END

SCENARIO 2 - Dtor call on passing an object as a by-value parameter
===================================================================

class T;        // Somewhere, a class T is defined.
void g(T t);    // Somewhere, a function g is defined,
                //   taking an instance of T as a by-value argument.

void f()
{
    T t;

// The difficulty is with the function call below. When object t is passed // to function g, T's copy-ctor is called. This copy-ctor call is present in // the AST and can be found by a "normal" tree traversal using an ASTVisitor. // However, the corresponding destructor call is not present in the AST.
    g(t);
}

=== END

SCENARIO 3 - Ctor call on returning an object
=============================================

class T;        // Somewhere, a class T is defined.

T f()
{
    T t;

// The "by-value" return of object t causes a call to the copy-ctor of T. // However, I could not find the call by a "normal" tree traversal using an
    // ASTVisitor.
    return t;
}

=== END

By a "normal" tree traversal I mean calling 'traverse' only once,
say on the TranslationUnit (and not calling 'traverse' manually on parts of the
tree that are not visited by default).

Now, my question is as follows:
* Is it possible to find these mentioned function calls by a normal tree traversal, - or, * Do I need to manually traverse different parts of the tree, which are not traversed by default, - or, * Do I need to infer certain function calls from the relevant contexts myself?

I am very interested in hearing what you think would be the proper way of locating these function calls.

In advance, thank you for your time,

Kind regards,

Hessel Hoogendorp
[EMAIL PROTECTED]

---- START ---- implicit.cc
tree = TranslationUnit:
  topForms:
    topForms[0] = TF_decl:
      loc = implicit.cc:1:1
      decl = Declaration:
        dflags = 
        spec = TS_classSpec:
          loc = implicit.cc:1:1
          cv = 
          keyword = struct
          name = PQ_name:
            loc = implicit.cc:1:8
            name = "T"
          bases:
          members = MemberList:
            list:
              list[0] = MR_func:
                loc = implicit.cc:1:1
                endloc = <noloc>:1:1
                f = Function:
                  funcType = ()()
                  receiver = T &__receiver, at implicit.cc:1:1 (0x09914218)
                  retVar: T &<retVar>, at implicit.cc:1:1 (0x099158C8)
                  dflags = inline (member) (implicit)
                  retspec = TS_type:
                    loc = implicit.cc:1:1
                    cv = 
                    type = T
                  nameAndParams = Declarator:
                    var: (member) (definition) (implicit) constructor-special() 
(2 overloadings)
                    context = DC_FUNCTION
                    decl = D_func:
                      loc = implicit.cc:1:1
                      base = D_name:
                        loc = implicit.cc:1:1
                        name = PQ_variable:
                          loc = implicit.cc:1:1
                          var = constructor-special()
                      params:
                      cv = 
                      exnSpec is null
                      kAndR_params:
                      ql = 
                    init is null
                    ctorStatement is null
                    dtorStatement is null
                  inits:
                  body = S_compound:
                    succ={ }
                    loc = implicit.cc:1:1
                    endloc = <noloc>:1:1
                    stmts:
                  handlers:
                  dtorStatement is null
                  implicitlyDefined = true
              list[1] = MR_func:
                loc = implicit.cc:1:1
                endloc = <noloc>:1:1
                f = Function:
                  funcType = ()(T const &__other)
                  receiver = T &__receiver, at implicit.cc:1:1 (0x09914158)
                  retVar: T &<retVar>, at implicit.cc:1:1 (0x09914058)
                  dflags = inline (member) (implicit)
                  retspec = TS_type:
                    loc = implicit.cc:1:1
                    cv = 
                    type = T
                  nameAndParams = Declarator:
                    var: (member) (definition) (implicit) constructor-special(T 
const &__other)
                    context = DC_FUNCTION
                    decl = D_func:
                      loc = implicit.cc:1:1
                      base = D_name:
                        loc = implicit.cc:1:1
                        name = PQ_variable:
                          loc = implicit.cc:1:1
                          var = constructor-special(T const &__other)
                      params:
                        params[0] = ASTTypeId:
                          spec = TS_type:
                            loc = implicit.cc:1:1
                            cv = 
                            type = T const &
                          decl = Declarator:
                            var: (parameter) T const &__other
                            context = DC_D_FUNC
                            decl = D_name:
                              loc = implicit.cc:1:1
                              name = PQ_variable:
                                loc = implicit.cc:1:1
                                var = T const &__other
                            init is null
                            ctorStatement is null
                            dtorStatement is null
                      cv = 
                      exnSpec is null
                      kAndR_params:
                      ql = 
                    init is null
                    ctorStatement is null
                    dtorStatement is null
                  inits:
                  body = S_compound:
                    succ={ }
                    loc = implicit.cc:1:1
                    endloc = <noloc>:1:1
                    stmts:
                  handlers:
                  dtorStatement is null
                  implicitlyDefined = true
              list[2] = MR_func:
                loc = implicit.cc:1:1
                endloc = <noloc>:1:1
                f = Function:
                  funcType = T &()(T const &__other)
                  receiver = T &__receiver, at implicit.cc:1:1 (0x09917D48)
                  retVar: NULL
                  dflags = inline (member) (implicit)
                  retspec = TS_type:
                    loc = implicit.cc:1:1
                    cv = 
                    type = T &
                  nameAndParams = Declarator:
                    var: (member) (definition) (implicit) T &operator=(T const 
&__other)
                    context = DC_FUNCTION
                    decl = D_func:
                      loc = implicit.cc:1:1
                      base = D_name:
                        loc = implicit.cc:1:1
                        name = PQ_variable:
                          loc = implicit.cc:1:1
                          var = T &operator=(T const &__other)
                      params:
                        params[0] = ASTTypeId:
                          spec = TS_type:
                            loc = implicit.cc:1:1
                            cv = 
                            type = T const &
                          decl = Declarator:
                            var: (parameter) T const &__other
                            context = DC_D_FUNC
                            decl = D_name:
                              loc = implicit.cc:1:1
                              name = PQ_variable:
                                loc = implicit.cc:1:1
                                var = T const &__other
                            init is null
                            ctorStatement is null
                            dtorStatement is null
                      cv = 
                      exnSpec is null
                      kAndR_params:
                      ql = 
                    init is null
                    ctorStatement is null
                    dtorStatement is null
                  inits:
                  body = S_compound:
                    succ={ }
                    loc = implicit.cc:1:1
                    endloc = <noloc>:1:1
                    stmts:
                      stmts[0] = S_return:
                        succ={ }
                        loc = implicit.cc:1:1
                        endloc = <noloc>:1:1
                        expr = FullExpression:
                          expr = E_deref:
                            type: T &
                            loc = implicit.cc:1:1
                            endloc = <noloc>:1:1
                            ptr = E_this:
                              type: T * const 
                              loc = implicit.cc:1:1
                              endloc = <noloc>:1:1
                        ctorStatement is null
                  handlers:
                  dtorStatement is null
                  implicitlyDefined = true
              list[3] = MR_func:
                loc = implicit.cc:1:1
                endloc = <noloc>:1:1
                f = Function:
                  funcType = ()()
                  receiver = T &__receiver, at implicit.cc:1:1 (0x09917EC0)
                  retVar: NULL
                  dflags = inline (member) (implicit)
                  retspec = TS_type:
                    loc = implicit.cc:1:1
                    cv = 
                    type = void
                  nameAndParams = Declarator:
                    var: (member) (definition) (implicit) ~T()
                    context = DC_FUNCTION
                    decl = D_func:
                      loc = implicit.cc:1:1
                      base = D_name:
                        loc = implicit.cc:1:1
                        name = PQ_variable:
                          loc = implicit.cc:1:1
                          var = ~T()
                      params:
                      cv = 
                      exnSpec is null
                      kAndR_params:
                      ql = 
                    init is null
                    ctorStatement is null
                    dtorStatement is null
                  inits:
                  body = S_compound:
                    succ={ }
                    loc = implicit.cc:1:1
                    endloc = <noloc>:1:1
                    stmts:
                  handlers:
                  dtorStatement = S_compound:
                    succ={ }
                    loc = implicit.cc:1:1
                    endloc = <noloc>:1:1
                    stmts:
                  implicitlyDefined = true
        decllist:
    topForms[1] = TF_func:
      loc = implicit.cc:4:1
      f = Function:
        funcType = void ()()
        receiver = NULL
        retVar: NULL
        dflags = 
        retspec = TS_simple:
          loc = implicit.cc:4:1
          cv = 
          id = void
        nameAndParams = Declarator:
          var: (global) (definition) void f()
          context = DC_FUNCTION
          decl = D_func:
            loc = implicit.cc:4:6
            base = D_name:
              loc = implicit.cc:4:6
              name = PQ_name:
                loc = implicit.cc:4:6
                name = "f"
            params:
            cv = 
            exnSpec is null
            kAndR_params:
            ql = 
          init is null
          ctorStatement is null
          dtorStatement is null
        inits:
        body = S_compound:
          succ={ }
          loc = implicit.cc:5:1
          endloc = implicit.cc:10:2
          stmts:
            stmts[0] = S_decl:
              succ={ }
              loc = implicit.cc:9:3
              endloc = implicit.cc:9:7
              decl = Declaration:
                dflags = 
                spec = TS_name:
                  loc = implicit.cc:9:3
                  cv = 
                  name = PQ_name:
                    loc = implicit.cc:9:3
                    name = "T"
                  typenameUsed = false
                decllist:
                  decllist[0] = Declarator:
                    var: (definition) T t
                    context = DC_S_DECL
                    decl = D_name:
                      loc = implicit.cc:9:5
                      name = PQ_name:
                        loc = implicit.cc:9:5
                        name = "t"
                    init = IN_ctor:
                      loc = implicit.cc:9:5
                      args:
                      was_IN_expr = false
                    ctorStatement = S_expr:
                      succ={ }
                      loc = implicit.cc:9:5
                      endloc = <noloc>:1:1
                      expr = FullExpression:
                        expr = E_constructor:
                          type: T
                          ctorVar: constructor-special(), at implicit.cc:1:1 
(0x09917B18)
                          loc = implicit.cc:9:5
                          endloc = <noloc>:1:1
                          spec = TS_type:
                            loc = implicit.cc:9:5
                            cv = 
                            type = T
                          args:
                          artificial = true
                          retObj = E_variable:
                            type: T &
                            var: T t, at implicit.cc:9:5 (0x099184B8)
                            loc = implicit.cc:9:5
                            endloc = <noloc>:1:1
                            name = PQ_variable:
                              loc = implicit.cc:9:5
                              var = T t
                    dtorStatement = S_expr:
                      succ={ }
                      loc = implicit.cc:9:5
                      endloc = <noloc>:1:1
                      expr = FullExpression:
                        expr = E_funCall:
                          type: void
                          loc = implicit.cc:9:5
                          endloc = <noloc>:1:1
                          func = E_fieldAcc:
                            type: ()()
                            field: ~T(), at implicit.cc:1:1 (0x09917F18)
                            loc = implicit.cc:9:5
                            endloc = <noloc>:1:1
                            obj = E_variable:
                              type: T &
                              var: T t, at implicit.cc:9:5 (0x099184B8)
                              loc = implicit.cc:9:5
                              endloc = <noloc>:1:1
                              name = PQ_variable:
                                loc = implicit.cc:9:5
                                var = T t
                            fieldName = PQ_variable:
                              loc = implicit.cc:9:5
                              var = ~T()
                          args:
                          retObj is null
        handlers:
        dtorStatement is null
        implicitlyDefined = false
---- STOP ----

_______________________________________________
dev-static-analysis mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-static-analysis

Reply via email to