Using non-qualified identifiers as DUContext scope IDs

Nicolás Alvarez nicolas.alvarez at gmail.com
Tue Apr 11 04:40:49 UTC 2017


Hi,

This is a continuation of my previous email about openDeclaration.

AbstractContextBuilder::openContext also takes a QualifiedIdentifier,
where it seems like taking a single Identifier would make more sense.
However, while a Declaration stores an Identifier (and openDeclaration
uses the last Identifier from a QID), a DUContext actually stores a
QualifiedIdentifier as its "localScopeIdentifier", so it's a tricker
situation. We need to look at that property too.

I think localScopeIdentifier should be an Identifier too. The full
scopeIdentifier() of a DUContext is formed by walking the parent
contexts and concatenating their Identifiers, so I don't see why each
local scope ID should be a QID. I think if you have multiple
components in a QID, you should have multiple nested contexts too.

The problem is that kdev-clang often creates DUContexts with
multi-component QIDs (ns::class or ns1::ns2::class), as I verified by
adding an assertion. Interestingly, many of these came from
kdev-clang's Visitor::createContext, which has this lovely comment:

"// wtf: why is the DUContext API requesting a QID when it needs a plain Id?!"

Making things even more interesting, I looked at a few cases where
kdev-clang was creating DUContexts with multi-component QIDs as scope
identifiers, and I found they are *wrong*. Here is an example
testcase:

namespace ns{} // necessary, don't know why

namespace ns {
    class vec {
    public:
        void reserve(int n);
    };
    void vec::reserve(int n) {
        int x=12;
        x+=2; //avoid "unused variable" warning
    }
}

At some point this will create the internal context for the reserve()
definition (at least that's what I think it is), with
localScopeIdentifier="ns::vec" (ie. a QualifiedIdentifier with
[Identifier("ns"), Identifier("vec")]). Its parent context is the
'foo' namespace. The full scopeIdentifier() of the context is thus
"ns::ns::vec", which is clearly wrong. This is even visible in the
GUI! The tooltip of the 'x' variable says "Scope:
ns::ns::vec::reserve".

This is clearly a bug, but I think it's not *just* a concrete bug in
kdev-clang that we fix and move on. I think there is *no* case where
it would make sense for a DUContext to have multiple ID components as
its scope QID. You should just create multiple nested contexts and
assign each a single identifier.

I propose:
1. add a warning or assertion in DUContext to ensure id.count() <= 1
2. fix problems in kdev-clang that trigger the above warning or
assertion (and maybe in other language plugins; I didn't try)
3. now that everyone passes a single-component QID, change DUContext
to store an Identifier instead of a QualifiedIdentifier, and change
APIs that create contexts accordingly

Comments?

-- 
Nicolás


More information about the KDevelop-devel mailing list