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