Skip to content

Commit 0bc405e

Browse files
committed
Remove DeclareMethods
1 parent a0925fb commit 0bc405e

File tree

6 files changed

+62
-66
lines changed

6 files changed

+62
-66
lines changed

compiler/rustc_codegen_llvm/src/context.rs

+11
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,17 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
433433
llvm::LLVMSetSection(g, section.as_ptr());
434434
}
435435
}
436+
437+
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
438+
if self.get_declared_value("main").is_none() {
439+
Some(self.declare_cfn("main", fn_type))
440+
} else {
441+
// If the symbol already exists, it is an error: for example, the user wrote
442+
// #[no_mangle] extern "C" fn main(..) {..}
443+
// instead of #[start]
444+
None
445+
}
446+
}
436447
}
437448

438449
impl CodegenCx<'b, 'tcx> {

compiler/rustc_codegen_llvm/src/declare.rs

+35-8
Original file line numberDiff line numberDiff line change
@@ -51,42 +51,69 @@ fn declare_raw_fn(
5151
llfn
5252
}
5353

54-
impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
55-
fn declare_global(&self, name: &str, ty: &'ll Type) -> &'ll Value {
54+
impl CodegenCx<'ll, 'tcx> {
55+
/// Declare a global value.
56+
///
57+
/// If there’s a value with the same name already declared, the function will
58+
/// return its Value instead.
59+
pub fn declare_global(&self, name: &str, ty: &'ll Type) -> &'ll Value {
5660
debug!("declare_global(name={:?})", name);
5761
unsafe { llvm::LLVMRustGetOrInsertGlobal(self.llmod, name.as_ptr().cast(), name.len(), ty) }
5862
}
5963

60-
fn declare_cfn(&self, name: &str, fn_type: &'ll Type) -> &'ll Value {
64+
/// Declare a C ABI function.
65+
///
66+
/// Only use this for foreign function ABIs and glue. For Rust functions use
67+
/// `declare_fn` instead.
68+
///
69+
/// If there’s a value with the same name already declared, the function will
70+
/// update the declaration and return existing Value instead.
71+
pub fn declare_cfn(&self, name: &str, fn_type: &'ll Type) -> &'ll Value {
6172
declare_raw_fn(self, name, llvm::CCallConv, fn_type)
6273
}
6374

64-
fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> &'ll Value {
75+
/// Declare a Rust function.
76+
///
77+
/// If there’s a value with the same name already declared, the function will
78+
/// update the declaration and return existing Value instead.
79+
pub fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> &'ll Value {
6580
debug!("declare_rust_fn(name={:?}, fn_abi={:?})", name, fn_abi);
6681

6782
let llfn = declare_raw_fn(self, name, fn_abi.llvm_cconv(), fn_abi.llvm_type(self));
6883
fn_abi.apply_attrs_llfn(self, llfn);
6984
llfn
7085
}
7186

72-
fn define_global(&self, name: &str, ty: &'ll Type) -> Option<&'ll Value> {
87+
/// Declare a global with an intention to define it.
88+
///
89+
/// Use this function when you intend to define a global. This function will
90+
/// return `None` if the name already has a definition associated with it. In that
91+
/// case an error should be reported to the user, because it usually happens due
92+
/// to user’s fault (e.g., misuse of `#[no_mangle]` or `#[export_name]` attributes).
93+
pub fn define_global(&self, name: &str, ty: &'ll Type) -> Option<&'ll Value> {
7394
if self.get_defined_value(name).is_some() {
7495
None
7596
} else {
7697
Some(self.declare_global(name, ty))
7798
}
7899
}
79100

80-
fn define_private_global(&self, ty: &'ll Type) -> &'ll Value {
101+
/// Declare a private global
102+
///
103+
/// Use this function when you intend to define a global without a name.
104+
pub fn define_private_global(&self, ty: &'ll Type) -> &'ll Value {
81105
unsafe { llvm::LLVMRustInsertPrivateGlobal(self.llmod, ty) }
82106
}
83107

84-
fn get_declared_value(&self, name: &str) -> Option<&'ll Value> {
108+
/// Gets declared value by name.
109+
pub fn get_declared_value(&self, name: &str) -> Option<&'ll Value> {
85110
debug!("get_declared_value(name={:?})", name);
86111
unsafe { llvm::LLVMRustGetNamedValue(self.llmod, name.as_ptr().cast(), name.len()) }
87112
}
88113

89-
fn get_defined_value(&self, name: &str) -> Option<&'ll Value> {
114+
/// Gets defined or externally defined (AvailableExternally linkage) value by
115+
/// name.
116+
pub fn get_defined_value(&self, name: &str) -> Option<&'ll Value> {
90117
self.get_declared_value(name).and_then(|val| {
91118
let declaration = unsafe { llvm::LLVMIsDeclaration(val) != 0 };
92119
if !declaration { Some(val) } else { None }

compiler/rustc_codegen_ssa/src/base.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -407,16 +407,18 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
407407
// listing.
408408
let main_ret_ty = cx.tcx().erase_regions(&main_ret_ty.no_bound_vars().unwrap());
409409

410-
if cx.get_declared_value("main").is_some() {
411-
// FIXME: We should be smart and show a better diagnostic here.
412-
cx.sess()
413-
.struct_span_err(sp, "entry symbol `main` declared multiple times")
414-
.help("did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead")
415-
.emit();
416-
cx.sess().abort_if_errors();
417-
bug!();
418-
}
419-
let llfn = cx.declare_cfn("main", llfty);
410+
let llfn = match cx.declare_c_main(llfty) {
411+
Some(llfn) => llfn,
412+
None => {
413+
// FIXME: We should be smart and show a better diagnostic here.
414+
cx.sess()
415+
.struct_span_err(sp, "entry symbol `main` declared multiple times")
416+
.help("did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead")
417+
.emit();
418+
cx.sess().abort_if_errors();
419+
bug!();
420+
}
421+
};
420422

421423
// `main` should respect same config for frame pointer elimination as rest of code
422424
cx.set_frame_pointer_elimination(llfn);

compiler/rustc_codegen_ssa/src/traits/declare.rs

+1-45
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,7 @@
11
use super::BackendTypes;
22
use rustc_hir::def_id::DefId;
33
use rustc_middle::mir::mono::{Linkage, Visibility};
4-
use rustc_middle::ty::{Instance, Ty};
5-
use rustc_target::abi::call::FnAbi;
6-
7-
pub trait DeclareMethods<'tcx>: BackendTypes {
8-
/// Declare a global value.
9-
///
10-
/// If there’s a value with the same name already declared, the function will
11-
/// return its Value instead.
12-
fn declare_global(&self, name: &str, ty: Self::Type) -> Self::Value;
13-
14-
/// Declare a C ABI function.
15-
///
16-
/// Only use this for foreign function ABIs and glue. For Rust functions use
17-
/// `declare_fn` instead.
18-
///
19-
/// If there’s a value with the same name already declared, the function will
20-
/// update the declaration and return existing Value instead.
21-
fn declare_cfn(&self, name: &str, fn_type: Self::Type) -> Self::Function;
22-
23-
/// Declare a Rust function.
24-
///
25-
/// If there’s a value with the same name already declared, the function will
26-
/// update the declaration and return existing Value instead.
27-
fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Function;
28-
29-
/// Declare a global with an intention to define it.
30-
///
31-
/// Use this function when you intend to define a global. This function will
32-
/// return `None` if the name already has a definition associated with it. In that
33-
/// case an error should be reported to the user, because it usually happens due
34-
/// to user’s fault (e.g., misuse of `#[no_mangle]` or `#[export_name]` attributes).
35-
fn define_global(&self, name: &str, ty: Self::Type) -> Option<Self::Value>;
36-
37-
/// Declare a private global
38-
///
39-
/// Use this function when you intend to define a global without a name.
40-
fn define_private_global(&self, ty: Self::Type) -> Self::Value;
41-
42-
/// Gets declared value by name.
43-
fn get_declared_value(&self, name: &str) -> Option<Self::Value>;
44-
45-
/// Gets defined or externally defined (AvailableExternally linkage) value by
46-
/// name.
47-
fn get_defined_value(&self, name: &str) -> Option<Self::Value>;
48-
}
4+
use rustc_middle::ty::Instance;
495

506
pub trait PreDefineMethods<'tcx>: BackendTypes {
517
fn predefine_static(

compiler/rustc_codegen_ssa/src/traits/misc.rs

+2
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ pub trait MiscMethods<'tcx>: BackendTypes {
1919
fn set_frame_pointer_elimination(&self, llfn: Self::Function);
2020
fn apply_target_cpu_attr(&self, llfn: Self::Function);
2121
fn create_used_variable(&self);
22+
/// Declares the extern "C" main function for the entry point. Returns None if the symbol already exists.
23+
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function>;
2224
}

compiler/rustc_codegen_ssa/src/traits/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub use self::builder::{BuilderMethods, OverflowOp};
3535
pub use self::consts::ConstMethods;
3636
pub use self::coverageinfo::{CoverageInfoBuilderMethods, CoverageInfoMethods};
3737
pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods};
38-
pub use self::declare::{DeclareMethods, PreDefineMethods};
38+
pub use self::declare::PreDefineMethods;
3939
pub use self::intrinsic::IntrinsicCallMethods;
4040
pub use self::misc::MiscMethods;
4141
pub use self::statics::{StaticBuilderMethods, StaticMethods};
@@ -60,7 +60,6 @@ pub trait CodegenMethods<'tcx>:
6060
+ StaticMethods
6161
+ CoverageInfoMethods
6262
+ DebugInfoMethods<'tcx>
63-
+ DeclareMethods<'tcx>
6463
+ AsmMethods
6564
+ PreDefineMethods<'tcx>
6665
+ HasParamEnv<'tcx>
@@ -77,7 +76,6 @@ impl<'tcx, T> CodegenMethods<'tcx> for T where
7776
+ StaticMethods
7877
+ CoverageInfoMethods
7978
+ DebugInfoMethods<'tcx>
80-
+ DeclareMethods<'tcx>
8179
+ AsmMethods
8280
+ PreDefineMethods<'tcx>
8381
+ HasParamEnv<'tcx>

0 commit comments

Comments
 (0)