Missing info from TypeLoc?

Hi all,

Given this c++ code:

const MyType *a;

The TypeSourceInfo from the VarDecl provides a TypeLoc that claims the type starts at "MyType" not "const". Is this by design or is there a bug here?

QualifiedTypeLoc does not store location information for the type qualifiers. This is “intentional” but clearly not ideal for tooling clients of type location information. Since the decl-specifiers for such a declaration can be in any order, the source range for such a type isn’t necessarily going to be useful, and you may be able to get the information you’re looking for by just looking at the start location of the Decl.

Is there an API I can re-use to parse the specifiers or at least get me part of the way toward what I need?

Is there an API I can re-use to parse the specifiers or at least get me part of the way toward what I need?

What is it that you need? :slight_smile:

I’m writing a tool to replace some part of the declaration with the ‘auto’ type specifier in the specific instance where a CXXNewExpr is the initializer. So like:

MyType *a = new MyType()

My problem is the handling of odd cases like:

Const MyType *a = new MyType(); → const auto *a = new MyType();

Const MyType *a = new const MyType(); → auto a = new const MyType();

Mytype * const a = new MyType(); → const auto a = new MyType();

// And so on

Really what I need is a way of locating the cv-qualifier and what it applies to so I can replace as much or as little with ‘auto’ as necessary. I was using TypeLoc to get the location information for the replacement but I need something more complex now.

It occurred to me that perhaps the best way to handle my problem is just to get the type info of the Decl from looking at Type hierarchy and just replace the whole declaration specifier instead of trying to replace parts of it. As Manuel pointed out earlier, things like function pointer and member pointer types will break with TypeLoc because the identifier is buried in the type definition.

I’ve continued to play with this problem in my spare time. I really believe there’s some necessary missing information somewhere.

So instead of replacing parts of the decl specifier with ‘auto’, leaving cv qualifiers behind, I went the route of simply replacing the decl specifier to avoid the problem of not being able to identify where the CV qualifiers are and what they’re attached to. The problem now is I can’t tell where the decl specifier begins or ends. Decl::getLocStart() will point to the start of the declaration but that appears to be all I get. Given the following:

const MyType * const ptr = ;

Decl::getLocStart() points to start of first const but not exactly ideal since this presumably would point to the start of other things in the decl specifier I don’t want to replace: storage specifiers and the like.

DeclaratorDecl::getTypeSpecStartLoc() points to MyType despite the name implying it should point to the start of the type specifier which should be the start of the first const.

This is a similar problem to the TypeSourceInfo missing the leading const. I know that QualifiedTypeLoc intentionally doesn’t provide source locations for the qualifiers but surely it should include the qualifiers in the range for the qualified type it represents? This still seems a deficiency to me. Could you point out the error in my understanding and/or point me at a function that properly points to the start of the type specifier?

Finally, how does one find the end of the type specifier? I realize for types like function pointers, etc the end might be after the declarator id but I need to know the end of the range to replace.

Given that this is legal:

const static int x = 0;

...you're probably going to have to replace the whole declaration anyway.


Sigh… I hadn’t thought of that. That makes full-out replacement a lot more complicated.