summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>2013-07-03 20:54:09 +0000
committerBill Schmidt <wschmidt@linux.vnet.ibm.com>2013-07-03 20:54:09 +0000
commit99a084b7ae1479f445ec4d20754ea3ebe720d528 (patch)
treebd5e1ff0603b3661acae028200a9d3498c502d54
parentfb7ace71cffc430c1af7a8fb6bfee717738a4378 (diff)
downloadbcm5719-llvm-99a084b7ae1479f445ec4d20754ea3ebe720d528.tar.gz
bcm5719-llvm-99a084b7ae1479f445ec4d20754ea3ebe720d528.zip
"bool" should be a context-sensitive keyword in Altivec mode.
PR16456 reported that Clang implements a hybrid between AltiVec's "Keyword and Predefine Method" and its "Context Sensitive Keyword Method," where "bool" is always a keyword, but "vector" and "pixel" are context-sensitive keywords. This isn't permitted by the AltiVec spec. For consistency with gcc, this patch implements the Context Sensitive Keyword Method for bool, and stops treating true and false as keywords in Altivec mode. The patch removes KEYALTIVEC as a trigger for defining these keywords in include/clang/Basic/TokenKinds.def, and adds logic for "vector bool" that mirrors the existing logic for "vector pixel." The test case is taken from the bug report. llvm-svn: 185580
-rw-r--r--clang/include/clang/Basic/TokenKinds.def6
-rw-r--r--clang/include/clang/Parse/Parser.h10
-rw-r--r--clang/include/clang/Sema/DeclSpec.h2
-rw-r--r--clang/lib/Parse/ParseDecl.cpp12
-rw-r--r--clang/lib/Parse/Parser.cpp1
-rw-r--r--clang/lib/Sema/DeclSpec.cpp14
-rw-r--r--clang/test/Parser/altivec-csk-bool.c14
7 files changed, 52 insertions, 7 deletions
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index c52a02eabb3..3f156a86a27 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -270,7 +270,7 @@ KEYWORD(__objc_no , KEYALL)
// C++ 2.11p1: Keywords.
KEYWORD(asm , KEYCXX|KEYGNU)
-KEYWORD(bool , BOOLSUPPORT|KEYALTIVEC)
+KEYWORD(bool , BOOLSUPPORT)
KEYWORD(catch , KEYCXX)
KEYWORD(class , KEYCXX)
KEYWORD(const_cast , KEYCXX)
@@ -278,7 +278,7 @@ KEYWORD(delete , KEYCXX)
KEYWORD(dynamic_cast , KEYCXX)
KEYWORD(explicit , KEYCXX)
KEYWORD(export , KEYCXX)
-KEYWORD(false , BOOLSUPPORT|KEYALTIVEC)
+KEYWORD(false , BOOLSUPPORT)
KEYWORD(friend , KEYCXX)
KEYWORD(mutable , KEYCXX)
KEYWORD(namespace , KEYCXX)
@@ -292,7 +292,7 @@ KEYWORD(static_cast , KEYCXX)
KEYWORD(template , KEYCXX)
KEYWORD(this , KEYCXX)
KEYWORD(throw , KEYCXX)
-KEYWORD(true , BOOLSUPPORT|KEYALTIVEC)
+KEYWORD(true , BOOLSUPPORT)
KEYWORD(try , KEYCXX)
KEYWORD(typename , KEYCXX)
KEYWORD(typeid , KEYCXX)
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index d3563bcf3e3..60201368158 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -105,11 +105,12 @@ class Parser : public CodeCompletionHandler {
/// Ident_super - IdentifierInfo for "super", to support fast
/// comparison.
IdentifierInfo *Ident_super;
- /// Ident_vector and Ident_pixel - cached IdentifierInfo's for
- /// "vector" and "pixel" fast comparison. Only present if
- /// AltiVec enabled.
+ /// Ident_vector, Ident_pixel, Ident_bool - cached IdentifierInfo's
+ /// for "vector", "pixel", and "bool" fast comparison. Only present
+ /// if AltiVec enabled.
IdentifierInfo *Ident_vector;
IdentifierInfo *Ident_pixel;
+ IdentifierInfo *Ident_bool;
/// Objective-C contextual keywords.
mutable IdentifierInfo *Ident_instancetype;
@@ -531,7 +532,8 @@ private:
bool &isInvalid) {
if (!getLangOpts().AltiVec ||
(Tok.getIdentifierInfo() != Ident_vector &&
- Tok.getIdentifierInfo() != Ident_pixel))
+ Tok.getIdentifierInfo() != Ident_pixel &&
+ Tok.getIdentifierInfo() != Ident_bool))
return false;
return TryAltiVecTokenOutOfLine(DS, Loc, PrevSpec, DiagID, isInvalid);
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 7ee2c6cc1e5..2d55c681a69 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -615,6 +615,8 @@ public:
const char *&PrevSpec, unsigned &DiagID);
bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID);
+ bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID);
bool SetTypeSpecError();
void UpdateDeclRep(Decl *Rep) {
assert(isDeclRep((TST) TypeSpecType));
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 451bf957219..b3e2a85965c 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5587,6 +5587,10 @@ bool Parser::TryAltiVecVectorTokenOutOfLine() {
Tok.setKind(tok::kw___vector);
return true;
}
+ if (Next.getIdentifierInfo() == Ident_bool) {
+ Tok.setKind(tok::kw___vector);
+ return true;
+ }
return false;
}
}
@@ -5615,6 +5619,10 @@ bool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
return true;
}
+ if (Next.getIdentifierInfo() == Ident_bool) {
+ isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+ return true;
+ }
break;
default:
break;
@@ -5623,6 +5631,10 @@ bool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
DS.isTypeAltiVecVector()) {
isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
return true;
+ } else if ((Tok.getIdentifierInfo() == Ident_bool) &&
+ DS.isTypeAltiVecVector()) {
+ isInvalid = DS.SetTypeAltiVecBool(true, Loc, PrevSpec, DiagID);
+ return true;
}
return false;
}
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index f19d24299aa..2c6d6b329dd 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -488,6 +488,7 @@ void Parser::Initialize() {
if (getLangOpts().AltiVec) {
Ident_vector = &PP.getIdentifierTable().get("vector");
Ident_pixel = &PP.getIdentifierTable().get("pixel");
+ Ident_bool = &PP.getIdentifierTable().get("bool");
}
Ident_introduced = 0;
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index dfce324b702..e75dc7b1bc9 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -707,6 +707,20 @@ bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
return false;
}
+bool DeclSpec::SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID) {
+ if (!TypeAltiVecVector || TypeAltiVecBool ||
+ (TypeSpecType != TST_unspecified)) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::err_invalid_vector_bool_decl_spec;
+ return true;
+ }
+ TypeAltiVecBool = isAltiVecBool;
+ TSTLoc = Loc;
+ TSTNameLoc = Loc;
+ return false;
+}
+
bool DeclSpec::SetTypeSpecError() {
TypeSpecType = TST_error;
TypeSpecOwned = false;
diff --git a/clang/test/Parser/altivec-csk-bool.c b/clang/test/Parser/altivec-csk-bool.c
new file mode 100644
index 00000000000..ba6fa3b2f77
--- /dev/null
+++ b/clang/test/Parser/altivec-csk-bool.c
@@ -0,0 +1,14 @@
+// RUN: %clang -target powerpc64-unknown-linux-gnu -maltivec -fsyntax-only %s
+
+// PR16456: Verify that bool, true, false are treated as context-sensitive
+// keywords (and therefore available for use as identifiers) when in
+// Altivec mode.
+
+typedef enum {
+ false_value = 0,
+ true_value = 1
+} bool;
+
+#define true true_value
+#define false false_value
+
OpenPOWER on IntegriCloud