Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -11805,7 +11805,11 @@ prev = prev->getPreviousDecl(); if (!prev) - Diag(var->getLocation(), diag::warn_missing_variable_declarations) << var; + Diag(var->getLocation(), diag::warn_missing_variable_declarations) + << var + << ((var->getStorageClass() != SC_Extern) + ? FixItHint::CreateInsertion(var->getBeginLoc(), "static ") + : FixItHint{}); } // Cache the result of checking for constant initialization. @@ -13209,7 +13213,11 @@ // global functions that fail to be declared in header files. const FunctionDecl *PossibleZeroParamPrototype = nullptr; if (ShouldWarnAboutMissingPrototype(FD, PossibleZeroParamPrototype)) { - Diag(FD->getLocation(), diag::warn_missing_prototype) << FD; + Diag(FD->getLocation(), diag::warn_missing_prototype) + << FD + << ((FD->getStorageClass() != SC_Extern) + ? FixItHint::CreateInsertion(FD->getBeginLoc(), "static ") + : FixItHint{}); if (PossibleZeroParamPrototype) { // We found a declaration that is not a prototype, Index: test/Sema/warn-missing-prototypes.c =================================================================== --- test/Sema/warn-missing-prototypes.c +++ test/Sema/warn-missing-prototypes.c @@ -4,6 +4,7 @@ int f(); int f(int x) { return x; } // expected-warning{{no previous prototype for function 'f'}} +// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:1-[[@LINE-1]]:1}:"static " static int g(int x) { return x; } @@ -13,6 +14,9 @@ int g2(int x) { return x; } +extern int g3(int x) { return x; } // expected-warning{{no previous prototype for function 'g3'}} +// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]{{.*}}}:"{{.*}}" + void test(void); int h3(); @@ -40,4 +44,4 @@ void not_a_prototype_test(); // expected-note{{this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function}} void not_a_prototype_test() { } // expected-warning{{no previous prototype for function 'not_a_prototype_test'}} -// CHECK: fix-it:"{{.*}}":{40:27-40:27}:"void" +// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:27-[[@LINE-3]]:27}:"void" Index: test/Sema/warn-missing-variable-declarations.c =================================================================== --- test/Sema/warn-missing-variable-declarations.c +++ test/Sema/warn-missing-variable-declarations.c @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -Wmissing-variable-declarations -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wmissing-variable-declarations -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s int vbad1; // expected-warning{{no previous extern declaration for non-static variable 'vbad1'}} +// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:1-[[@LINE-1]]:1}:"static " int vbad2; int vbad2 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad2'}} @@ -8,6 +10,7 @@ struct { int mgood1; } vbad3; // expected-warning{{no previous extern declaration for non-static variable 'vbad3'}} +// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:1}:"static " int vbad4; int vbad4 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad4'}} Index: test/SemaCXX/warn-missing-variable-declarations.cpp =================================================================== --- test/SemaCXX/warn-missing-variable-declarations.cpp +++ test/SemaCXX/warn-missing-variable-declarations.cpp @@ -1,11 +1,15 @@ -// RUN: %clang -Wmissing-variable-declarations -fsyntax-only -Xclang -verify -std=c++17 %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-variable-declarations -std=c++17 %s +// RUN: %clang_cc1 -fsyntax-only -Wmissing-variable-declarations -fdiagnostics-parseable-fixits -std=c++17 %s 2>&1 | FileCheck %s // Variable declarations that should trigger a warning. int vbad1; // expected-warning{{no previous extern declaration for non-static variable 'vbad1'}} +// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:1-[[@LINE-1]]:1}:"static " int vbad2 = 10; // expected-warning{{no previous extern declaration for non-static variable 'vbad2'}} +// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:1-[[@LINE-1]]:1}:"static " namespace x { int vbad3; // expected-warning{{no previous extern declaration for non-static variable 'vbad3'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:3}:"static " } // Variable declarations that should not trigger a warning. @@ -58,7 +62,9 @@ constexpr int constexpr_var = 0; inline constexpr int inline_constexpr_var = 0; extern const int extern_const_var = 0; // expected-warning {{no previous extern declaration}} +// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]{{.*}}}:"{{.*}}" extern constexpr int extern_constexpr_var = 0; // expected-warning {{no previous extern declaration}} +// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]{{.*}}}:"{{.*}}" template int var_template = 0; template constexpr int const_var_template = 0;