Skip to content

v0.6.9#47

Merged
quic-rnamburi merged 1 commit into
qualcomm:mainfrom
likivisw:main
Jul 16, 2026
Merged

v0.6.9#47
quic-rnamburi merged 1 commit into
qualcomm:mainfrom
likivisw:main

Conversation

@likivisw

Copy link
Copy Markdown
Contributor

Overview

This release fixes a gap in the beta analysis engine where nested declarations
(enums, typedefs, and friend class records) inside a class or struct were not
having their C++ access specifier (public, protected, private) recorded.
As a result, changes to a nested declaration's access level were previously
invisible to the diff engine. Version is bumped from 0.6.8 → 0.6.9.


What Changed

1. Access Specifier Now Captured for Nested Declarations

Previously, when the beta tree-builder visited a nested enum, typedef, or
friend class declaration, it did not call getAccessSpecifier() on that node.
This meant the AccessSpecifier field was absent from the AST node, so any
change to the access level of a nested type went undetected.

The fix ensures that every nested declaration type now records its access level
at parse time, making access-specifier changes a first-class detectable
difference.

Affected declaration kinds:

Declaration Kind Builder Function
Nested enum / enum class BuildEnumNode
Nested typedef BuildTypedefDecl
Nested friend CXX record BuildFriendCxxRecordDecl
Nested class/struct (already set; reinforced) BuildCXXRecordNode

Practical Example

Consider a header mylib.h that evolves between two versions:

v1/mylib.h — original layout:

namespace mylib {

    class Device {
    public:
        enum class PowerLevel { Low, Medium, High };   // public

    protected:
        enum class State { Idle, Running, Stopped };   // protected

    private:
        enum class ErrorCode { None, Timeout, Overflow }; // private
    };

    class Processor {
    public:
        typedef int    TaskId;     // public
        typedef double ClockFreq;  // public

    protected:
        typedef unsigned int CoreMask; // protected

    private:
        typedef long long CycleCount;  // private
    };
}

v2/mylib.h — access specifiers shuffled:

namespace mylib {

    class Device {
    protected:
        enum class PowerLevel { Low, Medium, High };   // was public  → now protected

    private:
        enum class State { Idle, Running, Stopped };   // was protected → now private

    public:
        enum class ErrorCode { None, Timeout, Overflow }; // was private → now public
    };

    class Processor {
    private:
        typedef int    TaskId;     // was public → now private
        typedef double ClockFreq;  // was public → now private

    public:
        typedef unsigned int CoreMask; // was protected → now public

    protected:
        typedef long long CycleCount;  // was private → now protected
    };
}

Before this fix — armor reported no differences for these nodes because the
AccessSpecifier field was never populated.

After this fix — armor correctly reports each access-level change. The JSON
diff output now looks like:

{
  "astDiff": [
    {
      "nodeType": "Class",
      "qualifiedName": "mylib::Device",
      "tag": "modified",
      "children": [
        {
          "nodeType": "Enum",
          "qualifiedName": "mylib::Device::PowerLevel",
          "tag": "modified",
          "children": [
            {
              "AccessSpecifier": "Public",
              "nodeType": "Enum",
              "qualifiedName": "mylib::Device::PowerLevel",
              "tag": "removed"
            },
            {
              "AccessSpecifier": "Protected",
              "nodeType": "Enum",
              "qualifiedName": "mylib::Device::PowerLevel",
              "tag": "added"
            }
          ]
        },
        {
          "nodeType": "Enum",
          "qualifiedName": "mylib::Device::State",
          "tag": "modified",
          "children": [
            {
              "AccessSpecifier": "Protected",
              "nodeType": "Enum",
              "qualifiedName": "mylib::Device::State",
              "tag": "removed"
            },
            {
              "AccessSpecifier": "Private",
              "nodeType": "Enum",
              "qualifiedName": "mylib::Device::State",
              "tag": "added"
            }
          ]
        }
      ]
    }
  ]
}

Each modified node now carries a "removed" child (old access level) and an
"added" child (new access level), giving a precise picture of what changed.

…ecls

Populate `access` in BuildEnumNode, BuildTypedefDecl, and BuildFriendCxxRecordDecl via getAccessSpecifier(). Add access_spec_decl_changes tests. Bump version to 0.6.9.

Signed-off-by: likith viswanath <likivisw@qti.qualcomm.com>
@quic-rnamburi
quic-rnamburi merged commit 342f4a9 into qualcomm:main Jul 16, 2026
8 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants