r360117 - Improve function / variable disambiguation.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue May 7 00:36:07 PDT 2019
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'}}
More information about the cfe-commits
mailing list