[cfe-dev] [patch] Knowing if "static" was written or not

Paolo Bolzoni paolo.bolzoni1 at studenti.unipr.it
Mon Feb 22 14:30:29 PST 2010

I followed the hints by Douglas and re-made the patch.  I added
getStorageClassAsWritten() in both FunctionDecl and VarDecl. Details about
the fixes wrt previous patch follow.


On Feb 8, 2010, at 12:25 AM, Paolo Bolzoni wrote:

>> The enclosed patch allows to differentiate between those functions and
>> variables explicitly marked with the keyword static and those functions
>> or variables that are marked static for semantic reason.
>> [...]
>> Currently there seems to be no way to distinguish between a function
>> that is static because the keyword static is there or because a previous
>> declaration was marked as static. My patch added few member functions to
>> FunctionDecl in order to allow making such a distinction.
>> It is already possible to detect the difference in the variables, but for
>> sake of clearness I also put a similar member function in VarDecl.
>I'm curious about why you're focusing on whether "static" was written explicitly rather than tackling the general problem of "what storage specifier was actually written?". For example, one could have:
>       static int i;
>       extern int i;
>where the semantic storage specifier of the second "i" is "static" but the storage specifier as written is "extern". Wouldn't it be more valuable to add, to both FunctionDecl and VarDecl, a
>       StorageClass getStorageClassAsWritten() const;

It is indeed more valuable, I just did not thought about this case.

>> As for C++, here we have an example of a static variable where the static
>> keyword does not appear:
>> struct A {
>>  static int a;
>> };
>> int A::a = -1; /* this one */
>Well, in this case you aren't allowed to write 'static', so we don't actually need to pass down the 'is static as written' bit in CXXMethodDecl and friends. For example, this isn't necessary:
>[old patch piece omitted]
>And CXXConversionDecl, CXXConstructorDecl, and CXXDestructorDecl nodes will never need "static as written" bits, because they can never be static.

Even though getStorageClassAsWritten() will never return 'static' on a
correct program, it might return 'extern', since it is possible to do
something such as the following:

struct A {
   operator void*();
extern A::operator void*() { return 0; }

>One last comment...
>Index: include/clang/Parse/DeclSpec.h
>--- include/clang/Parse/DeclSpec.h      (revision 95203)
>+++ include/clang/Parse/DeclSpec.h      (working copy)
>@@ -238,6 +240,11 @@
>+  bool isStaticSpecified() const { return SCS_static_specified; }
>+  SourceLocation getStaticSpecLoc() const { return isStaticSpecified()
>+                                            ? StorageClassSpecLoc
>+                                            : SourceLocation(); }
>I don't understand why this is needed. The DeclSpec will only have a single storage specifier; the one that was written in the source, along with the location of that storage specifier. It's only when we get into merging function or variable declarations that we change the effective storage class on the AST (but not in the DeclSpec).

You are right, I misunderstood a few details in DeclSpec.
Now this should be corrected.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.tar.gz
Type: application/x-gzip
Size: 8988 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100222/77c81d4e/attachment.bin>

More information about the cfe-dev mailing list