]> granicus.if.org Git - clang/commitdiff
libstdc++ 4.4 uses __is_signed as an identifier, while Clang treats it
authorDouglas Gregor <dgregor@apple.com>
Thu, 28 Apr 2011 15:48:45 +0000 (15:48 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 28 Apr 2011 15:48:45 +0000 (15:48 +0000)
as a keyword for the __is_signed type trait. Cope with this conflict
via some hackish recovery: if we see a declaration of the form

 static const bool __is_signed

then we stop treating __is_signed as a keyword and instead treat it as
an identifier. It's ugly, but it's better than making the __is_signed
type trait conditional on some language flag. Fixes PR9804.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130399 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseDecl.cpp
test/SemaCXX/libstdcxx_is_pod_hack.cpp

index 24a487c89c35df3e328ff7550f929de400b4a9a6..a20e90bd0ea38f3d0d7e4e4f201e84afd1ff32de 100644 (file)
@@ -1479,6 +1479,24 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
       continue;
     }
 
+    case tok::kw___is_signed:
+      // GNU libstdc++ 4.4 uses __is_signed as an identifier, but Clang
+      // typically treats it as a trait. If we see __is_signed as it appears
+      // in libstdc++, e.g.,
+      //
+      //   static const bool __is_signed;
+      //
+      // then treat __is_signed as an identifier rather than as a keyword.
+      if (DS.getTypeSpecType() == TST_bool &&
+          DS.getTypeQualifiers() == DeclSpec::TQ_const &&
+          DS.getStorageClassSpec() == DeclSpec::SCS_static) {
+        Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
+        Tok.setKind(tok::identifier);
+      }
+
+      // We're done with the declaration-specifiers.
+      goto DoneWithDeclSpec;
+        
       // typedef-name
     case tok::identifier: {
       // In C++, check to see if this is a scope specifier like foo::bar::, if
index 2e9203219536e87ca258ce034d8f049e9c95c988..3cc476dc2893c1629d0a0e34bc1a1b7dda27a91c 100644 (file)
@@ -11,3 +11,12 @@ struct __is_pod {
 };
 
 __is_pod<int> ipi;
+
+// Another, similar egregious hack for __is_signed, which is a type
+// trait in Embarcadero's compiler but is used as an identifier in
+// libstdc++.
+struct test_is_signed {
+  static const bool __is_signed = true;
+};
+
+bool check_signed = test_is_signed::__is_signed;