aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseDeclCXX.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-09-04 05:53:02 +0000
committerDouglas Gregor <dgregor@apple.com>2009-09-04 05:53:02 +0000
commitb117a60f7684261ddc8c8f14e8ef8a827e6af814 (patch)
tree3370eef9408e1e5367689e197a5d114304ecf0ba /lib/Parse/ParseDeclCXX.cpp
parente6585a7d71510be00a625686153f48d496d3bbf1 (diff)
Introduce an egregious hack to fix PR4828.
The problem this change addresses is that we treat __is_pod and __is_empty as keywords in C++, because they are built-in type traits in GCC >= 4.3. However, GNU libstdc++ 4.2 (and possibly earlier versions) define implementation-detail struct templates named __is_pod and __is_empty. This commit solves the problem by recognizing struct __is_pod and struct __is_empty as special token sequences. When one of these token sequences is encountered, the keyword (__is_pod or __is_empty) is implicitly downgraded to an identifier so that parsing can continue. This is an egregious hack, but it has the virtue of "just working" whether someone is using libstdc++ 4.2 or not, without the need for special flags. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80988 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDeclCXX.cpp')
-rw-r--r--lib/Parse/ParseDeclCXX.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 59359530e3..385b805113 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -536,6 +536,26 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
if (Tok.is(tok::kw___declspec))
Attr = ParseMicrosoftDeclSpec(Attr);
+ if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_pod)) {
+ // GNU libstdc++ 4.2 uses __is_pod as the name of a struct template, but
+ // __is_pod is a keyword in GCC >= 4.3. Therefore, when we see the
+ // token sequence "struct __is_pod", make __is_pod into a normal
+ // identifier rather than a keyword, to allow libstdc++ 4.2 to work
+ // properly.
+ Tok.getIdentifierInfo()->setTokenID(tok::identifier);
+ Tok.setKind(tok::identifier);
+ }
+
+ if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_empty)) {
+ // GNU libstdc++ 4.2 uses __is_empty as the name of a struct template, but
+ // __is_empty is a keyword in GCC >= 4.3. Therefore, when we see the
+ // token sequence "struct __is_empty", make __is_empty into a normal
+ // identifier rather than a keyword, to allow libstdc++ 4.2 to work
+ // properly.
+ Tok.getIdentifierInfo()->setTokenID(tok::identifier);
+ Tok.setKind(tok::identifier);
+ }
+
// Parse the (optional) nested-name-specifier.
CXXScopeSpec SS;
if (getLang().CPlusPlus &&