urazoff created this revision. urazoff added reviewers: sammccall, hokein, adamcz. Herald added a project: All. urazoff requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
With this patch, declarations containing unknown types are parsed like declarations, not like expressions. This leads to better diagnostics and yields InvalidDecl in AST (thus DeclRefExpr's to them) which is good for compiler users and AST consumers. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D137020 Files: clang/include/clang/Parse/Parser.h clang/lib/Parse/ParseDecl.cpp clang/test/Driver/types.c clang/test/Parser/CompoundStmtScope.c clang/test/Parser/opencl-atomics-cl20.cl clang/test/Parser/recovery.c clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl clang/test/SemaOpenCL/invalid-device-enqueue-types-cl3.0.cl clang/test/SemaOpenCL/invalid-pipes-cl1.2.cl
Index: clang/test/SemaOpenCL/invalid-pipes-cl1.2.cl =================================================================== --- clang/test/SemaOpenCL/invalid-pipes-cl1.2.cl +++ clang/test/SemaOpenCL/invalid-pipes-cl1.2.cl @@ -28,7 +28,7 @@ void bar(void) { reserve_id_t r; #if defined(__OPENCL_C_VERSION__) -// expected-error@-2 {{use of undeclared identifier 'reserve_id_t'}} +// expected-error@-2 {{unknown type name 'reserve_id_t'}} #else // expected-error@-4 {{unknown type name 'reserve_id_t'}} #endif Index: clang/test/SemaOpenCL/invalid-device-enqueue-types-cl3.0.cl =================================================================== --- clang/test/SemaOpenCL/invalid-device-enqueue-types-cl3.0.cl +++ clang/test/SemaOpenCL/invalid-device-enqueue-types-cl3.0.cl @@ -5,8 +5,8 @@ clk_event_t e; queue_t q; #ifndef __opencl_c_device_enqueue -// expected-error@-3 {{use of undeclared identifier 'clk_event_t'}} -// expected-error@-3 {{use of undeclared identifier 'queue_t'}} +// expected-error@-3 {{unknown type name 'clk_event_t'}} +// expected-error@-3 {{unknown type name 'queue_t'}} #else // expected-no-diagnostics #endif Index: clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl =================================================================== --- clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl +++ clang/test/SemaOpenCL/intel-subgroup-avc-ext-types.cl @@ -46,19 +46,19 @@ // expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_single_reference_streamin_t' with an expression of incompatible type '__private char'}} // expected-error@-14 {{initializing '__private intel_sub_group_avc_ime_dual_reference_streamin_t' with an expression of incompatible type 'int'}} #else -// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_mce_payload_t'}} -// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_payload_t'}} -// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ref_payload_t'}} -// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_sic_payload_t'}} -// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_mce_result_t'}} -// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_t'}} -// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ref_result_t'}} -// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_sic_result_t'}} -// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_single_reference_streamout_t'}} -// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_dual_reference_streamout_t'}} -// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_dual_reference_streamin_t'}} -// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_single_reference_streamin_t'}} -// expected-error@-28 {{use of undeclared identifier 'intel_sub_group_avc_ime_dual_reference_streamin_t'}} +// expected-error@-28 {{unknown type name 'intel_sub_group_avc_mce_payload_t'}} +// expected-error@-28 {{unknown type name 'intel_sub_group_avc_ime_payload_t'}} +// expected-error@-28 {{unknown type name 'intel_sub_group_avc_ref_payload_t'}} +// expected-error@-28 {{unknown type name 'intel_sub_group_avc_sic_payload_t'}} +// expected-error@-28 {{unknown type name 'intel_sub_group_avc_mce_result_t'}} +// expected-error@-28 {{unknown type name 'intel_sub_group_avc_ime_result_t'}} +// expected-error@-28 {{unknown type name 'intel_sub_group_avc_ref_result_t'}} +// expected-error@-28 {{unknown type name 'intel_sub_group_avc_sic_result_t'}} +// expected-error@-28 {{unknown type name 'intel_sub_group_avc_ime_result_single_reference_streamout_t'}} +// expected-error@-28 {{unknown type name 'intel_sub_group_avc_ime_result_dual_reference_streamout_t'}} +// expected-error@-28 {{unknown type name 'intel_sub_group_avc_ime_dual_reference_streamin_t'}} +// expected-error@-28 {{unknown type name 'intel_sub_group_avc_ime_single_reference_streamin_t'}} +// expected-error@-28 {{unknown type name 'intel_sub_group_avc_ime_dual_reference_streamin_t'}} #endif } @@ -75,13 +75,12 @@ // expected-error@-5 {{initializing '__private intel_sub_group_avc_ref_payload_t' with an expression of incompatible type '__private intel_sub_group_avc_ime_payload_t'}} // expected-error@-3 {{assigning to '__private intel_sub_group_avc_sic_result_t' from incompatible type '__private intel_sub_group_avc_ime_result_t'}} #else -// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_mce_payload_t'}} -// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_mce_payload_t'}} -// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_ime_payload_t'}} -// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_ref_payload_t'}} -// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_sic_result_t'}} -// expected-error@-11 {{use of undeclared identifier 'intel_sub_group_avc_ime_result_t'}} -// expected-error@-11 {{use of undeclared identifier 'result_sic'}} expected-error@-11 {{use of undeclared identifier 'result_ime'}} +// expected-error@-11 {{unknown type name 'intel_sub_group_avc_mce_payload_t'}} +// expected-error@-11 {{unknown type name 'intel_sub_group_avc_mce_payload_t'}} +// expected-error@-11 {{unknown type name 'intel_sub_group_avc_ime_payload_t'}} +// expected-error@-11 {{unknown type name 'intel_sub_group_avc_ref_payload_t'}} +// expected-error@-11 {{unknown type name 'intel_sub_group_avc_sic_result_t'}} +// expected-error@-11 {{unknown type name 'intel_sub_group_avc_ime_result_t'}} #endif } Index: clang/test/Parser/recovery.c =================================================================== --- clang/test/Parser/recovery.c +++ clang/test/Parser/recovery.c @@ -10,8 +10,8 @@ // Testcase derived from PR2692 static void f (char * (*g) (char **, int), char **p, ...) { char *s; - va_list v; // expected-error {{identifier}} - s = g (p, __builtin_va_arg(v, int)); // expected-error {{identifier}} + va_list v; // expected-error {{unknown type name 'va_list'}} + s = g (p, __builtin_va_arg(v, int)); } Index: clang/test/Parser/opencl-atomics-cl20.cl =================================================================== --- clang/test/Parser/opencl-atomics-cl20.cl +++ clang/test/Parser/opencl-atomics-cl20.cl @@ -17,10 +17,10 @@ atomic_float f; atomic_flag fl; #if !defined(LANG_VER_OK) -// expected-error@-5 {{use of undeclared identifier 'atomic_int'}} -// expected-error@-5 {{use of undeclared identifier 'atomic_uint'}} -// expected-error@-5 {{use of undeclared identifier 'atomic_float'}} -// expected-error@-5 {{use of undeclared identifier 'atomic_flag'}} +// expected-error@-5 {{unknown type name 'atomic_int'}} +// expected-error@-5 {{unknown type name 'atomic_uint'}} +// expected-error@-5 {{unknown type name 'atomic_float'}} +// expected-error@-5 {{unknown type name 'atomic_flag'}} #endif // Optional types @@ -35,28 +35,26 @@ // one of the extensions is not supported. Here we check with // `cl_khr_int64_base_atomics` only. #if !defined(LANG_VER_OK) || !defined(cl_khr_int64_base_atomics) -// expected-error@-11 {{use of undeclared identifier 'atomic_long'}} -// expected-error@-11 {{use of undeclared identifier 'atomic_ulong'}} -// expected-error@-11 {{use of undeclared identifier 'atomic_double'}} -#if defined(LANG_VER_OK) -// expected-error@-15 {{expected ';' after expression}} -// expected-error@-16 {{use of undeclared identifier 'l'}} -// expected-error@-16 {{expected ';' after expression}} -// expected-error@-17 {{use of undeclared identifier 'ul'}} -#endif +// expected-error@-11 {{unknown type name 'atomic_long'}} +// expected-error@-11 {{unknown type name 'atomic_ulong'}} +// expected-error@-11 {{unknown type name 'atomic_double'}} #if !defined(LANG_VER_OK) || defined(__SPIR64__) -// expected-error@-18 {{use of undeclared identifier 'atomic_size_t'}} -// expected-error@-16 {{use of undeclared identifier 'atomic_ptrdiff_t'}} -#if !defined(LANG_VER_OK) -// expected-error@-20 {{use of undeclared identifier 'atomic_intptr_t'}} -// expected-error@-20 {{use of undeclared identifier 'atomic_uintptr_t'}} +// expected-error@-12 {{unknown type name 'atomic_size_t'}} +// expected-error@-12 {{unknown type name 'atomic_intptr_t'}} +#if !defined(LANG_VER_OK) && defined(__SPIR64__) +// expected-error@-14 {{unknown type name 'atomic_intptr_t'; did you mean 'atomic_int'?}} +// expected-note@* {{'atomic_int' declared here}} +// expected-error@-16 {{unknown type name 'atomic_uintptr_t'}} +// expected-error@-16 {{unknown type name 'atomic_ptrdiff_t'}} #else -// expected-error@-24 {{expected ';' after expression}} -// expected-error@-25 {{use of undeclared identifier 's'}} -// expected-error@-25 {{unknown type name 'atomic_intptr_t'; did you mean 'atomic_int'?}} +#if defined(LANG_VER_OK) // expected-note@* {{'atomic_int' declared here}} -// expected-error@-26 {{unknown type name 'atomic_uintptr_t'; did you mean 'atomic_uint'?}} +// expected-error@-20 {{unknown type name 'atomic_uintptr_t'; did you mean 'atomic_uint'?}} // expected-note@* {{'atomic_uint' declared here}} +#else +// expected-error@-23 {{unknown type name 'atomic_uintptr_t'}} +#endif +// expected-error@-24 {{unknown type name 'atomic_ptrdiff_t'}} #endif #endif #endif Index: clang/test/Parser/CompoundStmtScope.c =================================================================== --- clang/test/Parser/CompoundStmtScope.c +++ clang/test/Parser/CompoundStmtScope.c @@ -4,5 +4,5 @@ { typedef float X; } - X Y; // expected-error {{use of undeclared identifier}} + X Y; // expected-error {{unknown type name 'X'}} } Index: clang/test/Driver/types.c =================================================================== --- clang/test/Driver/types.c +++ clang/test/Driver/types.c @@ -20,5 +20,5 @@ __uint128_t t; } -// CHECK: error: use of undeclared identifier '__int128_t' -// CHECK: error: use of undeclared identifier '__uint128_t' +// CHECK: error: unknown type name '__int128_t' +// CHECK: error: unknown type name '__uint128_t' Index: clang/lib/Parse/ParseDecl.cpp =================================================================== --- clang/lib/Parse/ParseDecl.cpp +++ clang/lib/Parse/ParseDecl.cpp @@ -5381,6 +5381,20 @@ } } +bool Parser::IsUnknownTypedefName() { + switch (NextToken().getKind()) { + default: + return false; + case tok::kw___attribute: + case tok::star: + case tok::identifier: + return true; + case tok::amp: + case tok::ampamp: + return getLangOpts().CPlusPlus; + } +} + /// isDeclarationSpecifier() - Return true if the current token is part of a /// declaration specifier. /// @@ -5405,6 +5419,11 @@ return false; if (TryAltiVecVectorToken()) return true; + // Handle things like "unknown *bar" as declaration for better + // diagnostics. Also it leads to creation of invalid declaration + // node in AST for such cases which is good for AST readers. + if (IsUnknownTypedefName() && !getLangOpts().ObjC) + return true; [[fallthrough]]; case tok::kw_decltype: // decltype(T())::type case tok::kw_typename: // typename T::type Index: clang/include/clang/Parse/Parser.h =================================================================== --- clang/include/clang/Parse/Parser.h +++ clang/include/clang/Parse/Parser.h @@ -2456,6 +2456,7 @@ ParsingDeclSpec &DS, llvm::function_ref<void(ParsingFieldDeclarator &)> FieldsCallback); + bool IsUnknownTypedefName(); bool isDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename, bool DisambiguatingWithExpression = false); bool isTypeSpecifierQualifier();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits