First stage of adding AltiVec support
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95335 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp
index 9e5f5a2..0f1063e 100644
--- a/lib/Parse/DeclSpec.cpp
+++ b/lib/Parse/DeclSpec.cpp
@@ -192,6 +192,7 @@
case DeclSpec::TST_decimal32: return "_Decimal32";
case DeclSpec::TST_decimal64: return "_Decimal64";
case DeclSpec::TST_decimal128: return "_Decimal128";
+ case DeclSpec::TST_pixel: return "__pixel";
case DeclSpec::TST_enum: return "enum";
case DeclSpec::TST_class: return "class";
case DeclSpec::TST_union: return "union";
@@ -253,6 +254,11 @@
return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
TypeSpecWidth = W;
TSWLoc = Loc;
+ if (TypeAltiVecVector && ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::warn_vector_long_decl_spec_combination;
+ return true;
+ }
return false;
}
@@ -289,6 +295,38 @@
TypeRep = Rep;
TSTLoc = Loc;
TypeSpecOwned = Owned;
+ if (TypeAltiVecVector && (TypeSpecType == TST_double)) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::err_invalid_vector_double_decl_spec_combination;
+ return true;
+ }
+ return false;
+}
+
+bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID) {
+ if (TypeSpecType != TST_unspecified) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::err_invalid_vector_decl_spec_combination;
+ return true;
+ }
+ TypeAltiVecVector = isAltiVecVector;
+ AltiVecLoc = Loc;
+ return false;
+}
+
+bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID) {
+ if (!TypeAltiVecVector || (TypeSpecType != TST_unspecified)) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::err_invalid_pixel_decl_spec_combination;
+ return true;
+ }
+ TypeSpecType = TST_int;
+ TypeSpecSign = TSS_unsigned;
+ TypeSpecWidth = TSW_short;
+ TypeAltiVecPixel = isAltiVecPixel;
+ TSTLoc = Loc;
return false;
}
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 9960238..7856e62 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -1029,6 +1029,10 @@
if (DS.hasTypeSpecifier())
goto DoneWithDeclSpec;
+ // Check for need to substitute AltiVec keyword tokens.
+ if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
+ break;
+
// It has to be available as a typedef too!
TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(),
Tok.getLocation(), CurScope);
@@ -1270,6 +1274,12 @@
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
DiagID);
break;
+ case tok::kw___vector:
+ isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+ break;
+ case tok::kw___pixel:
+ isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
+ break;
// class-specifier:
case tok::kw_class:
@@ -1395,6 +1405,7 @@
/// [OBJC] class-name objc-protocol-refs[opt] [TODO]
/// [OBJC] typedef-name objc-protocol-refs[opt] [TODO]
/// [C++0x] 'decltype' ( expression )
+/// [AltiVec] '__vector'
bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
const char *&PrevSpec,
unsigned &DiagID,
@@ -1404,6 +1415,10 @@
switch (Tok.getKind()) {
case tok::identifier: // foo::bar
+ // Check for need to substitute AltiVec keyword tokens.
+ if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
+ break;
+ // Fall through.
case tok::kw_typename: // typename foo::bar
// Annotate typenames and C++ scope specifiers. If we get one, just
// recurse to handle whatever we get.
@@ -1520,7 +1535,13 @@
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
DiagID);
break;
-
+ case tok::kw___vector:
+ isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+ break;
+ case tok::kw___pixel:
+ isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
+ break;
+
// class-specifier:
case tok::kw_class:
case tok::kw_struct:
@@ -1987,6 +2008,9 @@
default: return false;
case tok::identifier: // foo::bar
+ if (TryAltiVecVectorToken())
+ return true;
+ // Fall through.
case tok::kw_typename: // typename T::type
// Annotate typenames and C++ scope specifiers. If we get one, just
// recurse to handle whatever we get.
@@ -2032,6 +2056,7 @@
case tok::kw__Decimal32:
case tok::kw__Decimal64:
case tok::kw__Decimal128:
+ case tok::kw___vector:
// struct-or-union-specifier (C99) or class-specifier (C++)
case tok::kw_class:
@@ -2072,7 +2097,9 @@
// Unfortunate hack to support "Class.factoryMethod" notation.
if (getLang().ObjC1 && NextToken().is(tok::period))
return false;
- // Fall through
+ if (TryAltiVecVectorToken())
+ return true;
+ // Fall through.
case tok::kw_typename: // typename T::type
// Annotate typenames and C++ scope specifiers. If we get one, just
@@ -2123,6 +2150,7 @@
case tok::kw__Decimal32:
case tok::kw__Decimal64:
case tok::kw__Decimal128:
+ case tok::kw___vector:
// struct-or-union-specifier (C99) or class-specifier (C++)
case tok::kw_class:
@@ -2768,7 +2796,8 @@
// Alternatively, this parameter list may be an identifier list form for a
// K&R-style function: void foo(a,b,c)
- if (!getLang().CPlusPlus && Tok.is(tok::identifier)) {
+ if (!getLang().CPlusPlus && Tok.is(tok::identifier)
+ && !TryAltiVecVectorToken()) {
if (!TryAnnotateTypeOrScopeToken()) {
// K&R identifier lists can't have typedefs as identifiers, per
// C99 6.7.5.3p11.
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 669575c..c609136 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -780,6 +780,7 @@
case tok::kw_void:
case tok::kw_typename:
case tok::kw_typeof:
+ case tok::kw___vector:
case tok::annot_typename: {
if (!getLang().CPlusPlus) {
Diag(Tok, diag::err_expected_expression);
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index 51c5670..6251a2f 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -672,6 +672,11 @@
Parser::TPResult Parser::isCXXDeclarationSpecifier() {
switch (Tok.getKind()) {
case tok::identifier: // foo::bar
+ // Check for need to substitute AltiVec __vector keyword
+ // for "vector" identifier.
+ if (TryAltiVecVectorToken())
+ return TPResult::True();
+ // Fall through.
case tok::kw_typename: // typename T::type
// Annotate typenames and C++ scope specifiers. If we get one, just
// recurse to handle whatever we get.
@@ -750,6 +755,10 @@
case tok::kw___ptr64:
case tok::kw___forceinline:
return TPResult::True();
+
+ // AltiVec
+ case tok::kw___vector:
+ return TPResult::True();
case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed
// We've already annotated a scope; try to annotate a type.
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 63b0a27..f15b39a 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -346,6 +346,11 @@
}
Ident_super = &PP.getIdentifierTable().get("super");
+
+ if (getLang().AltiVec) {
+ Ident_vector = &PP.getIdentifierTable().get("vector");
+ Ident_pixel = &PP.getIdentifierTable().get("pixel");
+ }
}
/// ParseTopLevelDecl - Parse one top-level declaration, return whatever the