summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp14
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp4
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp4
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp6
4 files changed, 25 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index d84a10c6ba2..6ac7d29752d 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -1707,11 +1707,19 @@ bool ItaniumCXXABI::canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const {
if (CGM.getLangOpts().AppleKext)
return false;
- // If we don't have any not emitted inline virtual function, and if vtable is
- // not hidden, then we are safe to emit available_externally copy of vtable.
+ // If the vtable is hidden then it is not safe to emit an available_externally
+ // copy of vtable.
+ if (isVTableHidden(RD))
+ return false;
+
+ if (CGM.getCodeGenOpts().ForceEmitVTables)
+ return true;
+
+ // If we don't have any not emitted inline virtual function then we are safe
+ // to emit an available_externally copy of vtable.
// FIXME we can still emit a copy of the vtable if we
// can emit definition of the inline functions.
- return !hasAnyUnusedVirtualInlineFunction(RD) && !isVTableHidden(RD);
+ return !hasAnyUnusedVirtualInlineFunction(RD);
}
static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF,
Address InitialPtr,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 3eee463bb13..d392f68897c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3472,6 +3472,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_strict_vtable_pointers,
false))
CmdArgs.push_back("-fstrict-vtable-pointers");
+ if (Args.hasFlag(options::OPT_fforce_emit_vtables,
+ options::OPT_fno_force_emit_vtables,
+ false))
+ CmdArgs.push_back("-fforce-emit-vtables");
if (!Args.hasFlag(options::OPT_foptimize_sibling_calls,
options::OPT_fno_optimize_sibling_calls))
CmdArgs.push_back("-mdisable-tail-calls");
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index a959cdb2347..2aa74c38e2b 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -719,6 +719,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.StrictEnums = Args.hasArg(OPT_fstrict_enums);
Opts.StrictReturn = !Args.hasArg(OPT_fno_strict_return);
Opts.StrictVTablePointers = Args.hasArg(OPT_fstrict_vtable_pointers);
+ Opts.ForceEmitVTables = Args.hasArg(OPT_fforce_emit_vtables);
Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) ||
Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
Args.hasArg(OPT_cl_fast_relaxed_math);
@@ -2735,6 +2736,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Args.getAllArgValues(OPT_fxray_never_instrument);
Opts.XRayAttrListFiles = Args.getAllArgValues(OPT_fxray_attr_list);
+ // -fforce-emit-vtables
+ Opts.ForceEmitVTables = Args.hasArg(OPT_fforce_emit_vtables);
+
// -fallow-editor-placeholders
Opts.AllowEditorPlaceholders = Args.hasArg(OPT_fallow_editor_placeholders);
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 55517fc3f66..f5e48210924 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -6125,6 +6125,12 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
Record->setParamDestroyedInCallee(true);
else if (Record->hasNonTrivialDestructor())
Record->setParamDestroyedInCallee(CanPass);
+
+ if (getLangOpts().ForceEmitVTables) {
+ // If we want to emit all the vtables, we need to mark it as used. This
+ // is especially required for cases like vtable assumption loads.
+ MarkVTableUsed(Record->getInnerLocStart(), Record);
+ }
}
/// Look up the special member function that would be called by a special
OpenPOWER on IntegriCloud