diff options
author | Chris Lattner <sabre@nondot.org> | 2010-06-23 06:00:24 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-06-23 06:00:24 +0000 |
commit | 788b0fd67e1992f23555454efcdb16a19dfefac3 (patch) | |
tree | 9a2fb45262ab3d833202750f6cf4c5150ed2c521 /lib/Parse/DeclSpec.cpp | |
parent | 8dab6571b2cab96f44d0a1d6e3edbfdb68b7ed6b (diff) |
improve altivec vector bool/pixel support, patch by Anton Yartsev
with several tweaks by me.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106619 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/DeclSpec.cpp')
-rw-r--r-- | lib/Parse/DeclSpec.cpp | 55 |
1 files changed, 47 insertions, 8 deletions
diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp index 5dc08b3dfa..2f328b0e65 100644 --- a/lib/Parse/DeclSpec.cpp +++ b/lib/Parse/DeclSpec.cpp @@ -253,7 +253,8 @@ bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc, return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID); TypeSpecWidth = W; TSWLoc = Loc; - if (TypeAltiVecVector && ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { + if (TypeAltiVecVector && !TypeAltiVecBool && + ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); DiagID = diag::warn_vector_long_decl_spec_combination; return true; @@ -290,13 +291,18 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, DiagID = diag::err_invalid_decl_spec_combination; return true; } + if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) { + TypeAltiVecBool = true; + TSTLoc = Loc; + return false; + } TypeSpecType = T; TypeRep = Rep; TSTLoc = Loc; TypeSpecOwned = Owned; - if (TypeAltiVecVector && (TypeSpecType == TST_double)) { + if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) { PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); - DiagID = diag::err_invalid_vector_double_decl_spec_combination; + DiagID = diag::err_invalid_vector_decl_spec; return true; } return false; @@ -316,14 +322,12 @@ bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID) { - if (!TypeAltiVecVector || (TypeSpecType != TST_unspecified)) { + if (!TypeAltiVecVector || TypeAltiVecPixel || + (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; @@ -438,6 +442,42 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) { // Check the type specifier components first. SourceManager &SrcMgr = PP.getSourceManager(); + // Validate and finalize AltiVec vector declspec. + if (TypeAltiVecVector) { + if (TypeAltiVecBool) { + // Sign specifiers are not allowed with vector bool. (PIM 2.1) + if (TypeSpecSign != TSS_unspecified) { + Diag(D, TSSLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec) + << getSpecifierName((TSS)TypeSpecSign); + } + + // Only char/int are valid with vector bool. (PIM 2.1) + if ((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) && + (TypeSpecType != TST_int) || TypeAltiVecPixel) { + Diag(D, TSTLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec) + << (TypeAltiVecPixel ? "__pixel" : + getSpecifierName((TST)TypeSpecType)); + } + + // Only 'short' is valid with vector bool. (PIM 2.1) + if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short)) + Diag(D, TSWLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec) + << getSpecifierName((TSW)TypeSpecWidth); + + // Elements of vector bool are interpreted as unsigned. (PIM 2.1) + if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) || + (TypeSpecWidth != TSW_unspecified)) + TypeSpecSign = TSS_unsigned; + } + + if (TypeAltiVecPixel) { + //TODO: perform validation + TypeSpecType = TST_int; + TypeSpecSign = TSS_unsigned; + TypeSpecWidth = TSW_short; + } + } + // signed/unsigned are only valid with int/char/wchar_t. if (TypeSpecSign != TSS_unspecified) { if (TypeSpecType == TST_unspecified) @@ -513,7 +553,6 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) { ClearStorageClassSpecs(); } - // Okay, now we can infer the real type. // TODO: return "auto function" and other bad things based on the real type. |