// decl-specifier-seq '{' is not a parameter in C++11.
TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
InvalidAsDeclaration);
+ // A declaration-specifier (not followed by '(' or '{') means this can't be
+ // an expression, but it could still be a template argument.
+ if (TPR != TPResult::Ambiguous &&
+ !(VersusTemplateArgument && TPR == TPResult::True))
+ return TPR;
- if (VersusTemplateArgument && TPR == TPResult::True) {
- // Consume the decl-specifier-seq. We have to look past it, since a
- // type-id might appear here in a template argument.
- bool SeenType = false;
- do {
- SeenType |= isCXXDeclarationSpecifierAType();
- if (TryConsumeDeclarationSpecifier() == TPResult::Error)
- return TPResult::Error;
-
- // If we see a parameter name, this can't be a template argument.
- if (SeenType && Tok.is(tok::identifier))
- return TPResult::True;
-
- TPR = isCXXDeclarationSpecifier(TPResult::False,
- InvalidAsDeclaration);
- if (TPR == TPResult::Error)
- return TPR;
- } while (TPR != TPResult::False);
- } else if (TPR == TPResult::Ambiguous) {
- // Disambiguate what follows the decl-specifier.
+ bool SeenType = false;
+ do {
+ SeenType |= isCXXDeclarationSpecifierAType();
if (TryConsumeDeclarationSpecifier() == TPResult::Error)
return TPResult::Error;
- } else
- return TPR;
+
+ // If we see a parameter name, this can't be a template argument.
+ if (SeenType && Tok.is(tok::identifier))
+ return TPResult::True;
+
+ TPR = isCXXDeclarationSpecifier(TPResult::False,
+ InvalidAsDeclaration);
+ if (TPR == TPResult::Error)
+ return TPR;
+
+ // Two declaration-specifiers means this can't be an expression.
+ if (TPR == TPResult::True && !VersusTemplateArgument)
+ return TPR;
+ } while (TPR != TPResult::False);
// declarator
// abstract-declarator[opt]
const PrintingPolicy &Policy) {
assert(isTypeRep(T) && "T does not store a type");
assert(Rep && "no type provided!");
+ if (TypeSpecType == TST_error)
+ return false;
if (TypeSpecType != TST_unspecified) {
PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
DiagID = diag::err_invalid_decl_spec_combination;
const PrintingPolicy &Policy) {
assert(isExprRep(T) && "T does not store an expr");
assert(Rep && "no expression provided!");
+ if (TypeSpecType == TST_error)
+ return false;
if (TypeSpecType != TST_unspecified) {
PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
DiagID = diag::err_invalid_decl_spec_combination;
assert(isDeclRep(T) && "T does not store a decl");
// Unlike the other cases, we don't assert that we actually get a decl.
+ if (TypeSpecType == TST_error)
+ return false;
if (TypeSpecType != TST_unspecified) {
PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
DiagID = diag::err_invalid_decl_spec_combination;
const PrintingPolicy &Policy) {
assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&
"rep required for these type-spec kinds!");
+ if (TypeSpecType == TST_error)
+ return false;
if (TypeSpecType != TST_unspecified) {
PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
DiagID = diag::err_invalid_decl_spec_combination;
bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID,
const PrintingPolicy &Policy) {
+ if (TypeSpecType == TST_error)
+ return false;
if (TypeSpecType != TST_unspecified) {
PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
DiagID = diag::err_invalid_vector_decl_spec_combination;
bool DeclSpec::SetTypePipe(bool isPipe, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID,
const PrintingPolicy &Policy) {
-
+ if (TypeSpecType == TST_error)
+ return false;
if (TypeSpecType != TST_unspecified) {
PrevSpec = DeclSpec::getSpecifierName((TST)TypeSpecType, Policy);
DiagID = diag::err_invalid_decl_spec_combination;
bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID,
const PrintingPolicy &Policy) {
+ if (TypeSpecType == TST_error)
+ return false;
if (!TypeAltiVecVector || TypeAltiVecPixel ||
(TypeSpecType != TST_unspecified)) {
PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
bool DeclSpec::SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID,
const PrintingPolicy &Policy) {
+ if (TypeSpecType == TST_error)
+ return false;
if (!TypeAltiVecVector || TypeAltiVecBool ||
(TypeSpecType != TST_unspecified)) {
PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
// Before possibly changing their values, save specs as written.
SaveWrittenBuiltinSpecs();
- // Check the type specifier components first.
+ // Check the type specifier components first. No checking for an invalid
+ // type.
+ if (TypeSpecType == TST_error)
+ return;
// If decltype(auto) is used, no other type specifiers are permitted.
if (TypeSpecType == TST_decltype_auto &&
vector float res_vf;
// CHECK-NOALTIVEC: error: unknown type name 'vector'
+// CHECK-NOALTIVEC-NOT: '(error)'
signed char param_sc;
unsigned char param_uc;
// CHECK-LE: and <4 x i32> {{.*}}, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647>
// CHECK-LE: bitcast <4 x i32> %{{.*}} to <4 x float>
// CHECK-LE: store <4 x float> %{{.*}}, <4 x float>* @vf
-// CHECK-NOALTIVEC: error: use of undeclared identifier 'vf'
-// CHECK-NOALTIVEC: vf = vec_abs(vf)
vsc = vec_nabs(vsc);
// CHECK: sub <16 x i8> zeroinitializer
res_vi = vec_neg(vi);
// CHECK: sub <4 x i32> zeroinitializer, {{%[0-9]+}}
// CHECK-LE: sub <4 x i32> zeroinitializer, {{%[0-9]+}}
-// CHECK-NOALTIVEC: error: use of undeclared identifier 'vi'
-// CHECK-NOALTIVEC: vi = vec_neg(vi);
res_vs = vec_neg(vs);
// CHECK: sub <8 x i16> zeroinitializer, {{%[0-9]+}}
// CHECK-LE: sub <8 x i16> zeroinitializer, {{%[0-9]+}}
-// CHECK-NOALTIVEC: error: use of undeclared identifier 'vs'
-// CHECK-NOALTIVEC: res_vs = vec_neg(vs);
res_vsc = vec_neg(vsc);
// CHECK: sub <16 x i8> zeroinitializer, {{%[0-9]+}}
// CHECK-LE: sub <16 x i8> zeroinitializer, {{%[0-9]+}}
-// CHECK-NOALTIVEC: error: use of undeclared identifier 'vsc'
-// CHECK-NOALTIVEC: res_vsc = vec_neg(vsc);
/* vec_abs */