Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -893,7 +893,8 @@ def fno_force_enable_int128 : Flag<["-"], "fno-force-enable-int128">, Group, Flags<[CC1Option]>, HelpText<"Disable support for int128_t type">; - +def fkeep_static_consts : Flag<["-"], "fkeep-static-consts">, Group, Flags<[CC1Option]>, + HelpText<"Keep static const variables even if unused">; def ffixed_point : Flag<["-"], "ffixed-point">, Group, Flags<[CC1Option]>, HelpText<"Enable fixed point types">; def fno_fixed_point : Flag<["-"], "fno-fixed-point">, Group, Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -341,6 +341,9 @@ ENUM_CODEGENOPT(SignReturnAddress, SignReturnAddressScope, 2, None) +/// Whether to emit unused static constants. +CODEGENOPT(KeepStaticConsts, 1, 0) + #undef CODEGENOPT #undef ENUM_CODEGENOPT #undef VALUE_CODEGENOPT Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -1350,6 +1350,12 @@ if (D && D->hasAttr()) addUsedGlobal(GV); + + if (CodeGenOpts.KeepStaticConsts && D && isa(D)) { + const auto *VD = cast(D); + if (VD->getType().isConstQualified() && VD->getStorageClass() == SC_Static) + addUsedGlobal(GV); + } } bool CodeGenModule::GetCPUAndFeaturesAttributes(const Decl *D, @@ -1985,6 +1991,13 @@ if (LangOpts.EmitAllDecls) return true; + if (CodeGenOpts.KeepStaticConsts) { + const auto *VD = dyn_cast(Global); + if (VD && VD->getType().isConstQualified() && + VD->getStorageClass() == SC_Static) + return true; + } + return getContext().DeclMustBeEmitted(Global); } Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -4008,6 +4008,7 @@ Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names); Args.AddLastArg(CmdArgs, options::OPT_femulated_tls, options::OPT_fno_emulated_tls); + Args.AddLastArg(CmdArgs, options::OPT_fkeep_static_consts); // AltiVec-like language extensions aren't relevant for assembling. if (!isa(JA) || Output.getType() != types::TY_PP_Asm) Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1145,6 +1145,8 @@ << A->getAsString(Args) << A->getValue(); } + Opts.KeepStaticConsts = Args.hasArg(OPT_fkeep_static_consts); + return Success; } Index: test/CodeGen/keep-static-consts.cpp =================================================================== --- test/CodeGen/keep-static-consts.cpp +++ test/CodeGen/keep-static-consts.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fkeep-static-consts -emit-llvm %s -o - -triple=x86_64-unknown-linux-gnu | FileCheck %s + +// CHECK: @_ZL7srcvers = internal constant [4 x i8] c"xyz\00", align 1 +// CHECK: @llvm.used = appending global [1 x i8*] [i8* getelementptr inbounds ([4 x i8], [4 x i8]* @_ZL7srcvers, i32 0, i32 0)], section "llvm.metadata" +static const char srcvers[] = "xyz"; +extern const int b = 1;