Author: rsmith Date: Tue May 7 00:36:07 2019 New Revision: 360117 URL: http://llvm.org/viewvc/llvm-project?rev=360117&view=rev Log: Improve function / variable disambiguation.
Keep looking for decl-specifiers after an unknown identifier. Don't issue diagnostics about an error type specifier conflicting with later type specifiers. Modified: cfe/trunk/lib/Parse/ParseDecl.cpp cfe/trunk/lib/Parse/ParseTentative.cpp cfe/trunk/lib/Sema/DeclSpec.cpp cfe/trunk/test/CodeGen/builtins-ppc-altivec.c cfe/trunk/test/Parser/cxx-ambig-decl-expr.cpp Modified: cfe/trunk/lib/Parse/ParseDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=360117&r1=360116&r2=360117&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) +++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue May 7 00:36:07 2019 @@ -2743,7 +2743,7 @@ bool Parser::ParseImplicitInt(DeclSpec & // TODO: Could inject an invalid typedef decl in an enclosing scope to // avoid rippling error messages on subsequent uses of the same type, // could be useful if #include was forgotten. - return false; + return true; } /// Determine the declaration specifier context from the declarator Modified: cfe/trunk/lib/Parse/ParseTentative.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=360117&r1=360116&r2=360117&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseTentative.cpp (original) +++ cfe/trunk/lib/Parse/ParseTentative.cpp Tue May 7 00:36:07 2019 @@ -1884,31 +1884,31 @@ Parser::TryParseParameterDeclarationClau // 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] Modified: cfe/trunk/lib/Sema/DeclSpec.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=360117&r1=360116&r2=360117&view=diff ============================================================================== --- cfe/trunk/lib/Sema/DeclSpec.cpp (original) +++ cfe/trunk/lib/Sema/DeclSpec.cpp Tue May 7 00:36:07 2019 @@ -706,6 +706,8 @@ bool DeclSpec::SetTypeSpecType(TST T, So 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; @@ -726,6 +728,8 @@ bool DeclSpec::SetTypeSpecType(TST T, So 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; @@ -756,6 +760,8 @@ bool DeclSpec::SetTypeSpecType(TST T, So 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; @@ -775,6 +781,8 @@ bool DeclSpec::SetTypeSpecType(TST T, So 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; @@ -807,6 +815,8 @@ bool DeclSpec::SetTypeSpecSat(SourceLoca 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; @@ -820,7 +830,8 @@ bool DeclSpec::SetTypeAltiVecVector(bool 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; @@ -836,6 +847,8 @@ bool DeclSpec::SetTypePipe(bool isPipe, 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); @@ -851,6 +864,8 @@ bool DeclSpec::SetTypeAltiVecPixel(bool 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); @@ -1033,7 +1048,10 @@ void DeclSpec::Finish(Sema &S, const Pri // 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 && Modified: cfe/trunk/test/CodeGen/builtins-ppc-altivec.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtins-ppc-altivec.c?rev=360117&r1=360116&r2=360117&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/builtins-ppc-altivec.c (original) +++ cfe/trunk/test/CodeGen/builtins-ppc-altivec.c Tue May 7 00:36:07 2019 @@ -37,6 +37,7 @@ vector unsigned int res_vui; vector float res_vf; // CHECK-NOALTIVEC: error: unknown type name 'vector' +// CHECK-NOALTIVEC-NOT: '(error)' signed char param_sc; unsigned char param_uc; @@ -86,8 +87,6 @@ void test1() { // 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 @@ -110,20 +109,14 @@ void test1() { 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 */ Modified: cfe/trunk/test/Parser/cxx-ambig-decl-expr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-ambig-decl-expr.cpp?rev=360117&r1=360116&r2=360117&view=diff ============================================================================== --- cfe/trunk/test/Parser/cxx-ambig-decl-expr.cpp (original) +++ cfe/trunk/test/Parser/cxx-ambig-decl-expr.cpp Tue May 7 00:36:07 2019 @@ -15,3 +15,5 @@ void f() { auto (*p)() -> int(nullptr); auto (*q)() -> int(*)(unknown); // expected-error {{unknown type name 'unknown'}} auto (*r)() -> int(*)(unknown + 1); // expected-error {{undeclared identifier 'unknown'}} + +int f(unknown const x); // expected-error {{unknown type name 'unknown'}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits