aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/ASTContext.h3
-rw-r--r--include/clang/AST/Type.h33
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td8
-rw-r--r--include/clang/Basic/Specifiers.h1
-rw-r--r--include/clang/Basic/TokenKinds.def10
-rw-r--r--include/clang/Parse/DeclSpec.h14
-rw-r--r--include/clang/Parse/Parser.h80
-rw-r--r--lib/AST/ASTContext.cpp20
-rw-r--r--lib/AST/TypePrinter.cpp27
-rw-r--r--lib/Basic/IdentifierTable.cpp4
-rw-r--r--lib/Frontend/PCHReader.cpp8
-rw-r--r--lib/Frontend/PCHWriter.cpp2
-rw-r--r--lib/Parse/DeclSpec.cpp38
-rw-r--r--lib/Parse/ParseDecl.cpp35
-rw-r--r--lib/Parse/ParseExpr.cpp1
-rw-r--r--lib/Parse/ParseTentative.cpp9
-rw-r--r--lib/Parse/Parser.cpp5
-rw-r--r--lib/Sema/SemaType.cpp7
-rw-r--r--lib/Sema/TreeTransform.h12
-rw-r--r--test/Parser/altivec.c91
-rw-r--r--test/Parser/cxx-altivec.cpp108
21 files changed, 474 insertions, 42 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 18b09a2b21..6fa6e30deb 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -502,7 +502,8 @@ public:
/// getVectorType - Return the unique reference to a vector type of
/// the specified element type and size. VectorType must be a built-in type.
- QualType getVectorType(QualType VectorType, unsigned NumElts);
+ QualType getVectorType(QualType VectorType, unsigned NumElts,
+ bool AltiVec, bool IsPixel);
/// getExtVectorType - Return the unique reference to an extended vector type
/// of the specified element type and size. VectorType must be a built-in
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index fa5d3e105f..4e213ed785 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1594,7 +1594,8 @@ public:
/// VectorType - GCC generic vector type. This type is created using
/// __attribute__((vector_size(n)), where "n" specifies the vector size in
-/// bytes. Since the constructor takes the number of vector elements, the
+/// bytes; or from an Altivec __vector or vector declaration.
+/// Since the constructor takes the number of vector elements, the
/// client is responsible for converting the size into the number of elements.
class VectorType : public Type, public llvm::FoldingSetNode {
protected:
@@ -1604,13 +1605,21 @@ protected:
/// NumElements - The number of elements in the vector.
unsigned NumElements;
- VectorType(QualType vecType, unsigned nElements, QualType canonType) :
+ /// AltiVec - True if this is for an Altivec vector.
+ bool AltiVec;
+
+ /// Pixel - True if this is for an Altivec vector pixel.
+ bool Pixel;
+
+ VectorType(QualType vecType, unsigned nElements, QualType canonType,
+ bool isAltiVec, bool isPixel) :
Type(Vector, canonType, vecType->isDependentType()),
- ElementType(vecType), NumElements(nElements) {}
+ ElementType(vecType), NumElements(nElements),
+ AltiVec(isAltiVec), Pixel(isPixel) {}
VectorType(TypeClass tc, QualType vecType, unsigned nElements,
- QualType canonType)
+ QualType canonType, bool isAltiVec, bool isPixel)
: Type(tc, canonType, vecType->isDependentType()), ElementType(vecType),
- NumElements(nElements) {}
+ NumElements(nElements), AltiVec(isAltiVec), Pixel(isPixel) {}
friend class ASTContext; // ASTContext creates these.
public:
@@ -1620,14 +1629,22 @@ public:
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
+ bool isAltiVec() const { return AltiVec; }
+
+ bool isPixel() const { return Pixel; }
+
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getElementType(), getNumElements(), getTypeClass());
+ Profile(ID, getElementType(), getNumElements(), getTypeClass(),
+ AltiVec, Pixel);
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
- unsigned NumElements, TypeClass TypeClass) {
+ unsigned NumElements, TypeClass TypeClass,
+ bool isAltiVec, bool isPixel) {
ID.AddPointer(ElementType.getAsOpaquePtr());
ID.AddInteger(NumElements);
ID.AddInteger(TypeClass);
+ ID.AddBoolean(isAltiVec);
+ ID.AddBoolean(isPixel);
}
virtual Linkage getLinkage() const;
@@ -1645,7 +1662,7 @@ public:
/// points, colors, and textures (modeled after OpenGL Shading Language).
class ExtVectorType : public VectorType {
ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) :
- VectorType(ExtVector, vecType, nElements, canonType) {}
+ VectorType(ExtVector, vecType, nElements, canonType, false, false) {}
friend class ASTContext; // ASTContext creates these.
public:
static int getPointAccessorIdx(char c) {
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index dc83e87e96..04e3daffe7 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -160,6 +160,14 @@ def err_typename_invalid_functionspec : Error<
"type name does not allow function specifier to be specified">;
def err_invalid_decl_spec_combination : Error<
"cannot combine with previous '%0' declaration specifier">;
+def err_invalid_vector_decl_spec_combination : Error<
+ "cannot combine with previous '%0' declaration specifier. \"__vector\" must be first">;
+def err_invalid_pixel_decl_spec_combination : Error<
+ "\"__pixel\" must be preceded by \"__vector\". '%0' declaration specifier not allowed here">;
+def err_invalid_vector_double_decl_spec_combination : Error<
+ "cannot use \"double\" with \"__vector\"">;
+def warn_vector_long_decl_spec_combination : Warning<
+ "Use of \"long\" with \"__vector\" is deprecated">;
def err_friend_invalid_in_context : Error<
"'friend' used outside of class">;
def err_unknown_typename : Error<
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index 9e54762add..3b60b689ae 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -46,6 +46,7 @@ namespace clang {
TST_decimal32, // _Decimal32
TST_decimal64, // _Decimal64
TST_decimal128, // _Decimal128
+ TST_pixel, // AltiVec
TST_enum,
TST_union,
TST_struct,
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index bb022f1175..522ac13b4e 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -227,7 +227,7 @@ KEYWORD(__func__ , KEYALL)
// C++ 2.11p1: Keywords.
KEYWORD(asm , KEYCXX|KEYGNU)
-KEYWORD(bool , BOOLSUPPORT)
+KEYWORD(bool , BOOLSUPPORT|KEYALTIVEC)
KEYWORD(catch , KEYCXX)
KEYWORD(class , KEYCXX)
KEYWORD(const_cast , KEYCXX)
@@ -235,7 +235,7 @@ KEYWORD(delete , KEYCXX)
KEYWORD(dynamic_cast , KEYCXX)
KEYWORD(explicit , KEYCXX)
KEYWORD(export , KEYCXX)
-KEYWORD(false , BOOLSUPPORT)
+KEYWORD(false , BOOLSUPPORT|KEYALTIVEC)
KEYWORD(friend , KEYCXX)
KEYWORD(mutable , KEYCXX)
KEYWORD(namespace , KEYCXX)
@@ -249,7 +249,7 @@ KEYWORD(static_cast , KEYCXX)
KEYWORD(template , KEYCXX)
KEYWORD(this , KEYCXX)
KEYWORD(throw , KEYCXX)
-KEYWORD(true , BOOLSUPPORT)
+KEYWORD(true , BOOLSUPPORT|KEYALTIVEC)
KEYWORD(try , KEYCXX)
KEYWORD(typename , KEYCXX)
KEYWORD(typeid , KEYCXX)
@@ -340,6 +340,10 @@ KEYWORD(__ptr64 , KEYALL)
KEYWORD(__w64 , KEYALL)
KEYWORD(__forceinline , KEYALL)
+// Altivec Extension.
+KEYWORD(__vector , KEYALTIVEC)
+KEYWORD(__pixel , KEYALTIVEC)
+
// Alternate spelling for various tokens. There are GCC extensions in all
// languages, but should not be disabled in strict conformance mode.
ALIAS("__attribute__", __attribute, KEYALL)
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index f923b5e910..c3fc952bdd 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -113,6 +113,7 @@ public:
static const TST TST_decimal32 = clang::TST_decimal32;
static const TST TST_decimal64 = clang::TST_decimal64;
static const TST TST_decimal128 = clang::TST_decimal128;
+ static const TST TST_pixel = clang::TST_pixel;
static const TST TST_enum = clang::TST_enum;
static const TST TST_union = clang::TST_union;
static const TST TST_struct = clang::TST_struct;
@@ -153,6 +154,8 @@ private:
/*TSC*/unsigned TypeSpecComplex : 2;
/*TSS*/unsigned TypeSpecSign : 2;
/*TST*/unsigned TypeSpecType : 5;
+ bool TypeAltiVecVector : 1;
+ bool TypeAltiVecPixel : 1;
bool TypeSpecOwned : 1;
// type-qualifiers
@@ -193,7 +196,7 @@ private:
SourceRange Range;
SourceLocation StorageClassSpecLoc, SCS_threadLoc;
- SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc;
+ SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc, AltiVecLoc;
SourceRange TypeofParensRange;
SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc;
SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc;
@@ -213,6 +216,8 @@ public:
TypeSpecComplex(TSC_unspecified),
TypeSpecSign(TSS_unspecified),
TypeSpecType(TST_unspecified),
+ TypeAltiVecVector(false),
+ TypeAltiVecPixel(false),
TypeSpecOwned(false),
TypeQualifiers(TSS_unspecified),
FS_inline_specified(false),
@@ -250,6 +255,8 @@ public:
TSC getTypeSpecComplex() const { return (TSC)TypeSpecComplex; }
TSS getTypeSpecSign() const { return (TSS)TypeSpecSign; }
TST getTypeSpecType() const { return (TST)TypeSpecType; }
+ bool isTypeAltiVecVector() const { return TypeAltiVecVector; }
+ bool isTypeAltiVecPixel() const { return TypeAltiVecPixel; }
bool isTypeSpecOwned() const { return TypeSpecOwned; }
void *getTypeRep() const { return TypeRep; }
CXXScopeSpec &getTypeSpecScope() { return TypeScope; }
@@ -260,6 +267,7 @@ public:
SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; }
SourceLocation getTypeSpecSignLoc() const { return TSSLoc; }
SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; }
+ SourceLocation getAltiVecLoc() const { return AltiVecLoc; }
SourceRange getTypeofParensRange() const { return TypeofParensRange; }
void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; }
@@ -344,6 +352,10 @@ public:
unsigned &DiagID);
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
unsigned &DiagID, void *Rep = 0, bool Owned = false);
+ bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID);
+ bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID);
bool SetTypeSpecError();
void UpdateTypeRep(void *Rep) { TypeRep = Rep; }
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 71aa38a155..f4d3d3e54d 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -81,6 +81,11 @@ class Parser {
/// 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.
+ IdentifierInfo *Ident_vector;
+ IdentifierInfo *Ident_pixel;
llvm::OwningPtr<PragmaHandler> PackHandler;
llvm::OwningPtr<PragmaHandler> UnusedHandler;
@@ -320,6 +325,81 @@ private:
/// annotated.
bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
+ /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens,
+ /// replacing them with the non-context-sensitive keywords. This returns
+ /// true if the token was replaced.
+ bool TryAltiVecToken(DeclSpec &DS, SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID, bool &isInvalid) {
+ if (getLang().AltiVec) {
+ if (Tok.getIdentifierInfo() == Ident_vector) {
+ const Token nextToken = NextToken();
+ switch (nextToken.getKind()) {
+ case tok::kw_short:
+ case tok::kw_long:
+ case tok::kw_signed:
+ case tok::kw_unsigned:
+ case tok::kw_void:
+ case tok::kw_char:
+ case tok::kw_int:
+ case tok::kw_float:
+ case tok::kw_double:
+ case tok::kw_bool:
+ case tok::kw___pixel:
+ isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+ return true;
+ case tok::identifier:
+ if (nextToken.getIdentifierInfo() == Ident_pixel) {
+ isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
+ DS.isTypeAltiVecVector()) {
+ isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /// TryAltiVecVectorToken - Check for context-sensitive AltiVec vector
+ /// identifier token, replacing it with the non-context-sensitive __vector.
+ /// This returns true if the token was replaced.
+ bool TryAltiVecVectorToken() {
+ if (getLang().AltiVec) {
+ if (Tok.getIdentifierInfo() == Ident_vector) {
+ const Token nextToken = NextToken();
+ switch (nextToken.getKind()) {
+ case tok::kw_short:
+ case tok::kw_long:
+ case tok::kw_signed:
+ case tok::kw_unsigned:
+ case tok::kw_void:
+ case tok::kw_char:
+ case tok::kw_int:
+ case tok::kw_float:
+ case tok::kw_double:
+ case tok::kw_bool:
+ case tok::kw___pixel:
+ Tok.setKind(tok::kw___vector);
+ return true;
+ case tok::identifier:
+ if (nextToken.getIdentifierInfo() == Ident_pixel) {
+ Tok.setKind(tok::kw___vector);
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return false;
+ }
+
/// TentativeParsingAction - An object that is used as a kind of "tentative
/// parsing transaction". It gets instantiated to mark the token position and
/// after the token consumption is done, Commit() or Revert() is called to
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 676be72787..b61ce8e529 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1610,7 +1610,8 @@ QualType ASTContext::getIncompleteArrayType(QualType EltTy,
/// getVectorType - Return the unique reference to a vector type of
/// the specified element type and size. VectorType must be a built-in type.
-QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) {
+QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
+ bool IsAltiVec, bool IsPixel) {
BuiltinType *baseType;
baseType = dyn_cast<BuiltinType>(getCanonicalType(vecType).getTypePtr());
@@ -1618,7 +1619,8 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) {
// Check if we've already instantiated a vector of this type.
llvm::FoldingSetNodeID ID;
- VectorType::Profile(ID, vecType, NumElts, Type::Vector);
+ VectorType::Profile(ID, vecType, NumElts, Type::Vector,
+ IsAltiVec, IsPixel);
void *InsertPos = 0;
if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(VTP, 0);
@@ -1626,15 +1628,16 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) {
// If the element type isn't canonical, this won't be a canonical type either,
// so fill in the canonical type field.
QualType Canonical;
- if (!vecType.isCanonical()) {
- Canonical = getVectorType(getCanonicalType(vecType), NumElts);
+ if (!vecType.isCanonical() || IsAltiVec || IsPixel) {
+ Canonical = getVectorType(getCanonicalType(vecType),
+ NumElts, false, false);
// Get the new insert position for the node we care about.
VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
}
VectorType *New = new (*this, TypeAlignment)
- VectorType(vecType, NumElts, Canonical);
+ VectorType(vecType, NumElts, Canonical, IsAltiVec, IsPixel);
VectorTypes.InsertNode(New, InsertPos);
Types.push_back(New);
return QualType(New, 0);
@@ -1650,7 +1653,7 @@ QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) {
// Check if we've already instantiated a vector of this type.
llvm::FoldingSetNodeID ID;
- VectorType::Profile(ID, vecType, NumElts, Type::ExtVector);
+ VectorType::Profile(ID, vecType, NumElts, Type::ExtVector, false, false);
void *InsertPos = 0;
if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(VTP, 0);
@@ -4636,7 +4639,7 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) {
// Turn <4 x signed int> -> <4 x unsigned int>
if (const VectorType *VTy = T->getAs<VectorType>())
return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()),
- VTy->getNumElements());
+ VTy->getNumElements(), VTy->isAltiVec(), VTy->isPixel());
// For enums, we return the unsigned version of the base type.
if (const EnumType *ETy = T->getAs<EnumType>())
@@ -4793,7 +4796,8 @@ static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context,
Str = End;
QualType ElementType = DecodeTypeFromStr(Str, Context, Error, false);
- Type = Context.getVectorType(ElementType, NumElements);
+ // FIXME: Don't know what to do about AltiVec.
+ Type = Context.getVectorType(ElementType, NumElements, false, false);
break;
}
case 'X': {
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 597ab37d2b..5b621cf728 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -225,15 +225,24 @@ void TypePrinter::PrintDependentSizedExtVector(
}
void TypePrinter::PrintVector(const VectorType *T, std::string &S) {
- // FIXME: We prefer to print the size directly here, but have no way
- // to get the size of the type.
- Print(T->getElementType(), S);
- std::string V = "__attribute__((__vector_size__(";
- V += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
- std::string ET;
- Print(T->getElementType(), ET);
- V += " * sizeof(" + ET + ")))) ";
- S = V + S;
+ if (T->isAltiVec()) {
+ if (T->isPixel())
+ S = "__vector __pixel " + S;
+ else {
+ Print(T->getElementType(), S);
+ S = "__vector " + S;
+ }
+ } else {
+ // FIXME: We prefer to print the size directly here, but have no way
+ // to get the size of the type.
+ Print(T->getElementType(), S);
+ std::string V = "__attribute__((__vector_size__(";
+ V += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
+ std::string ET;
+ Print(T->getElementType(), ET);
+ V += " * sizeof(" + ET + ")))) ";
+ S = V + S;
+ }
}
void TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) {
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index 401e6cba06..16a61b7156 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/lib/Basic/IdentifierTable.cpp
@@ -68,7 +68,8 @@ namespace {
KEYCXX0X = 8,
KEYGNU = 16,
KEYMS = 32,
- BOOLSUPPORT = 64
+ BOOLSUPPORT = 64,
+ KEYALTIVEC = 128
};
}
@@ -91,6 +92,7 @@ static void AddKeyword(const char *Keyword, unsigned KWLen,
else if (LangOpts.GNUMode && (Flags & KEYGNU)) AddResult = 1;
else if (LangOpts.Microsoft && (Flags & KEYMS)) AddResult = 1;
else if (LangOpts.Bool && (Flags & BOOLSUPPORT)) AddResult = 2;
+ else if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) AddResult = 2;
// Don't add this keyword if disabled in this language.
if (AddResult == 0) return;
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index bd93cf6b08..1ed5260a88 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -1880,18 +1880,20 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
}
case pch::TYPE_VECTOR: {
- if (Record.size() != 2) {
+ if (Record.size() != 4) {
Error("incorrect encoding of vector type in PCH file");
return QualType();
}
QualType ElementType = GetType(Record[0]);
unsigned NumElements = Record[1];
- return Context->getVectorType(ElementType, NumElements);
+ bool AltiVec = Record[2];
+ bool Pixel = Record[3];
+ return Context->getVectorType(ElementType, NumElements, AltiVec, Pixel);
}
case pch::TYPE_EXT_VECTOR: {
- if (Record.size() != 2) {
+ if (Record.size() != 4) {
Error("incorrect encoding of extended vector type in PCH file");
return QualType();
}
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index caf1ce47a1..a87b8cde2c 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -128,6 +128,8 @@ void PCHTypeWriter::VisitVariableArrayType(const VariableArrayType *T) {
void PCHTypeWriter::VisitVectorType(const VectorType *T) {
Writer.AddTypeRef(T->getElementType(), Record);
Record.push_back(T->getNumElements());
+ Record.push_back(T->isAltiVec());
+ Record.push_back(T->isPixel());
Code = pch::TYPE_VECTOR;
}
diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp
index 9e5f5a2ac0..0f1063eb3c 100644
--- a/lib/Parse/DeclSpec.cpp
+++ b/lib/Parse/DeclSpec.cpp
@@ -192,6 +192,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
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 @@ 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))) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::warn_vector_long_decl_spec_combination;
+ return true;
+ }
return false;
}
@@ -289,6 +295,38 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
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 9960238300..7856e62f04 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -1029,6 +1029,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
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 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
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 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
/// [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 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
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 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
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 @@ bool Parser::isTypeSpecifierQualifier() {
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 @@ bool Parser::isTypeSpecifierQualifier() {
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 @@ bool Parser::isDeclarationSpecifier() {
// 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 @@ bool Parser::isDeclarationSpecifier() {
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 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
// 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 669575c4f0..c6091367fd 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -780,6 +780,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
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 51c56706bb..6251a2f367 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -672,6 +672,11 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
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 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() {
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 63b0a27c08..f15b39a83e 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -346,6 +346,11 @@ void Parser::Initialize() {
}
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
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 8833792494..60f3b19060 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -343,6 +343,11 @@ static QualType ConvertDeclSpecToType(Declarator &TheDeclarator, Sema &TheSema){
if (TheSema.getLangOptions().Freestanding)
TheSema.Diag(DS.getTypeSpecComplexLoc(), diag::ext_freestanding_complex);
Result = Context.getComplexType(Result);
+ } else if (DS.isTypeAltiVecVector()) {
+ unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(Result));
+ assert(typeSize > 0 && "type size for vector must be greater than 0 bits");
+ Result = Context.getVectorType(Result, 128/typeSize, true,
+ DS.isTypeAltiVecPixel());
}
assert(DS.getTypeSpecComplex() != DeclSpec::TSC_imaginary &&
@@ -1753,7 +1758,7 @@ static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr, S
// Success! Instantiate the vector type, the number of elements is > 0, and
// not required to be a power of 2, unlike GCC.
- CurType = S.Context.getVectorType(CurType, vectorSize/typeSize);