[cfe-dev] Bugs 2746 and 3261

Eli Friedman eli.friedman at gmail.com
Wed Jan 14 12:59:52 PST 2009


On Wed, Jan 14, 2009 at 7:29 AM, Paolo Bolzoni <bolzoni at cs.unipr.it> wrote:
> Let's see a simple but evocative example.
> I have the clang AST of this code segment.
>
> Using the function that overrides
> HandleTranslationUnit(clang::TranslationUnit&)
> I want to pretty print:
>
> Here the code:
> struct B;
>
> struct A {
>  struct B* b;
> };
>
> struct B {
>  struct A* a;
> };

Okay, so at this point, all types are defined, so isDefinition()
returns true, so you can't figure out whether it was defined at a
certain point.

> The tree has three RecordDecl, visiting the first and pretty printing is easy.
> But when I am in the second, isDefinition() returns true and I loop in the
> field declarations; for each I get field name, if it is a bitfield and
> eventually the related expression and a type.
> The type is struct B (pointer a part), even if I recall the SourceLocation of
> the FieldDecl (or the including RecordDecl) while visiting the type, how can I
> know that the declaration is not actually there?

The approach I was thinking of is something like the following:
suppose you're trying to pretty-print the "struct B* b;" bit.  Let S
designate the location immediately before the keyword "struct", let E
designate the location immediately after the semicolon, and let D
designate the beginning of the definition of struct B.  We can
conclude that "struct B* b;" doesn't contain the definition of B by
looking at the locations: D is after E, so the field declaration
cannot contain the definition.  Similar reasoning applies for "struct
A* a;"; let S to E be the field declaration, and let D be the
beginning of the definition of struct A.  D is before S, so the field
declaration doesn't contain the definition.

Unfortunately, though, there isn't any easy way to compare source
locations like that; it should be possible, I think, but I don't know
the details of how to write it.  Also, I'm not sure if you can get the
relevant source locations easily, particularly S.  I think ongoing
work with DeclGroups will help here eventually, but I'm not sure of
the details.

There is another possible approach: take the location of the beginning
of the first declarator in the declaration (the "*b" bit), and scan
backwards through the source code to see if you find a "}" before the
first occurrence of the "struct" keyword.  It's quite messy in terms
of layering, and I'm not sure how preprocessor stuff would factor into
it, but I think it's feasible.  I don't know the details here either,
but I remember reading that the ObjC rewriter does some similar stuff.

I'm putting cfe-dev back onto the CC list so that people more familiar
with this stuff can comment; this is really outside the stuff I've
really tried.

-Eli



More information about the cfe-dev mailing list