about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkhyperia <github@khyperia.com>2020-09-18 13:06:53 +0200
committerkhyperia <github@khyperia.com>2020-09-18 13:11:59 +0200
commit0bc405e3521d84cfaef7d94f1ae40c6c16796c8b (patch)
tree4e0d5091a86c6debd8513a2a1ab9dd8e69f0daca
parenta0925fba747b4cf910592540aa1f817778dc315c (diff)
downloadrust-0bc405e3521d84cfaef7d94f1ae40c6c16796c8b.tar.gz
rust-0bc405e3521d84cfaef7d94f1ae40c6c16796c8b.zip
Remove DeclareMethods
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs11
-rw-r--r--compiler/rustc_codegen_llvm/src/declare.rs43
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs22
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/declare.rs46
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/misc.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/mod.rs4
6 files changed, 62 insertions, 66 deletions
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 1c51a9df5d8..1696f35563d 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -433,6 +433,17 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             llvm::LLVMSetSection(g, section.as_ptr());
         }
     }
+
+    fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
+        if self.get_declared_value("main").is_none() {
+            Some(self.declare_cfn("main", fn_type))
+        } else {
+            // If the symbol already exists, it is an error: for example, the user wrote
+            // #[no_mangle] extern "C" fn main(..) {..}
+            // instead of #[start]
+            None
+        }
+    }
 }
 
 impl CodegenCx<'b, 'tcx> {
diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs
index ec42bd4a039..a3d6882940a 100644
--- a/compiler/rustc_codegen_llvm/src/declare.rs
+++ b/compiler/rustc_codegen_llvm/src/declare.rs
@@ -51,17 +51,32 @@ fn declare_raw_fn(
     llfn
 }
 
-impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
-    fn declare_global(&self, name: &str, ty: &'ll Type) -> &'ll Value {
+impl CodegenCx<'ll, 'tcx> {
+    /// Declare a global value.
+    ///
+    /// If there’s a value with the same name already declared, the function will
+    /// return its Value instead.
+    pub fn declare_global(&self, name: &str, ty: &'ll Type) -> &'ll Value {
         debug!("declare_global(name={:?})", name);
         unsafe { llvm::LLVMRustGetOrInsertGlobal(self.llmod, name.as_ptr().cast(), name.len(), ty) }
     }
 
-    fn declare_cfn(&self, name: &str, fn_type: &'ll Type) -> &'ll Value {
+    /// Declare a C ABI function.
+    ///
+    /// Only use this for foreign function ABIs and glue. For Rust functions use
+    /// `declare_fn` instead.
+    ///
+    /// If there’s a value with the same name already declared, the function will
+    /// update the declaration and return existing Value instead.
+    pub fn declare_cfn(&self, name: &str, fn_type: &'ll Type) -> &'ll Value {
         declare_raw_fn(self, name, llvm::CCallConv, fn_type)
     }
 
-    fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> &'ll Value {
+    /// Declare a Rust function.
+    ///
+    /// If there’s a value with the same name already declared, the function will
+    /// update the declaration and return existing Value instead.
+    pub fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> &'ll Value {
         debug!("declare_rust_fn(name={:?}, fn_abi={:?})", name, fn_abi);
 
         let llfn = declare_raw_fn(self, name, fn_abi.llvm_cconv(), fn_abi.llvm_type(self));
@@ -69,7 +84,13 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         llfn
     }
 
-    fn define_global(&self, name: &str, ty: &'ll Type) -> Option<&'ll Value> {
+    /// Declare a global with an intention to define it.
+    ///
+    /// Use this function when you intend to define a global. This function will
+    /// return `None` if the name already has a definition associated with it. In that
+    /// case an error should be reported to the user, because it usually happens due
+    /// to user’s fault (e.g., misuse of `#[no_mangle]` or `#[export_name]` attributes).
+    pub fn define_global(&self, name: &str, ty: &'ll Type) -> Option<&'ll Value> {
         if self.get_defined_value(name).is_some() {
             None
         } else {
@@ -77,16 +98,22 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         }
     }
 
-    fn define_private_global(&self, ty: &'ll Type) -> &'ll Value {
+    /// Declare a private global
+    ///
+    /// Use this function when you intend to define a global without a name.
+    pub fn define_private_global(&self, ty: &'ll Type) -> &'ll Value {
         unsafe { llvm::LLVMRustInsertPrivateGlobal(self.llmod, ty) }
     }
 
-    fn get_declared_value(&self, name: &str) -> Option<&'ll Value> {
+    /// Gets declared value by name.
+    pub fn get_declared_value(&self, name: &str) -> Option<&'ll Value> {
         debug!("get_declared_value(name={:?})", name);
         unsafe { llvm::LLVMRustGetNamedValue(self.llmod, name.as_ptr().cast(), name.len()) }
     }
 
-    fn get_defined_value(&self, name: &str) -> Option<&'ll Value> {
+    /// Gets defined or externally defined (AvailableExternally linkage) value by
+    /// name.
+    pub fn get_defined_value(&self, name: &str) -> Option<&'ll Value> {
         self.get_declared_value(name).and_then(|val| {
             let declaration = unsafe { llvm::LLVMIsDeclaration(val) != 0 };
             if !declaration { Some(val) } else { None }
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 6fc849969a4..d82fc2c9f63 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -407,16 +407,18 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         // listing.
         let main_ret_ty = cx.tcx().erase_regions(&main_ret_ty.no_bound_vars().unwrap());
 
-        if cx.get_declared_value("main").is_some() {
-            // FIXME: We should be smart and show a better diagnostic here.
-            cx.sess()
-                .struct_span_err(sp, "entry symbol `main` declared multiple times")
-                .help("did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead")
-                .emit();
-            cx.sess().abort_if_errors();
-            bug!();
-        }
-        let llfn = cx.declare_cfn("main", llfty);
+        let llfn = match cx.declare_c_main(llfty) {
+            Some(llfn) => llfn,
+            None => {
+                // FIXME: We should be smart and show a better diagnostic here.
+                cx.sess()
+                    .struct_span_err(sp, "entry symbol `main` declared multiple times")
+                    .help("did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead")
+                    .emit();
+                cx.sess().abort_if_errors();
+                bug!();
+            }
+        };
 
         // `main` should respect same config for frame pointer elimination as rest of code
         cx.set_frame_pointer_elimination(llfn);
diff --git a/compiler/rustc_codegen_ssa/src/traits/declare.rs b/compiler/rustc_codegen_ssa/src/traits/declare.rs
index 690aacd2056..655afcd17f0 100644
--- a/compiler/rustc_codegen_ssa/src/traits/declare.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/declare.rs
@@ -1,51 +1,7 @@
 use super::BackendTypes;
 use rustc_hir::def_id::DefId;
 use rustc_middle::mir::mono::{Linkage, Visibility};
-use rustc_middle::ty::{Instance, Ty};
-use rustc_target::abi::call::FnAbi;
-
-pub trait DeclareMethods<'tcx>: BackendTypes {
-    /// Declare a global value.
-    ///
-    /// If there’s a value with the same name already declared, the function will
-    /// return its Value instead.
-    fn declare_global(&self, name: &str, ty: Self::Type) -> Self::Value;
-
-    /// Declare a C ABI function.
-    ///
-    /// Only use this for foreign function ABIs and glue. For Rust functions use
-    /// `declare_fn` instead.
-    ///
-    /// If there’s a value with the same name already declared, the function will
-    /// update the declaration and return existing Value instead.
-    fn declare_cfn(&self, name: &str, fn_type: Self::Type) -> Self::Function;
-
-    /// Declare a Rust function.
-    ///
-    /// If there’s a value with the same name already declared, the function will
-    /// update the declaration and return existing Value instead.
-    fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Function;
-
-    /// Declare a global with an intention to define it.
-    ///
-    /// Use this function when you intend to define a global. This function will
-    /// return `None` if the name already has a definition associated with it. In that
-    /// case an error should be reported to the user, because it usually happens due
-    /// to user’s fault (e.g., misuse of `#[no_mangle]` or `#[export_name]` attributes).
-    fn define_global(&self, name: &str, ty: Self::Type) -> Option<Self::Value>;
-
-    /// Declare a private global
-    ///
-    /// Use this function when you intend to define a global without a name.
-    fn define_private_global(&self, ty: Self::Type) -> Self::Value;
-
-    /// Gets declared value by name.
-    fn get_declared_value(&self, name: &str) -> Option<Self::Value>;
-
-    /// Gets defined or externally defined (AvailableExternally linkage) value by
-    /// name.
-    fn get_defined_value(&self, name: &str) -> Option<Self::Value>;
-}
+use rustc_middle::ty::Instance;
 
 pub trait PreDefineMethods<'tcx>: BackendTypes {
     fn predefine_static(
diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs
index fc57a9a80b2..6fff64bfcb6 100644
--- a/compiler/rustc_codegen_ssa/src/traits/misc.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs
@@ -19,4 +19,6 @@ pub trait MiscMethods<'tcx>: BackendTypes {
     fn set_frame_pointer_elimination(&self, llfn: Self::Function);
     fn apply_target_cpu_attr(&self, llfn: Self::Function);
     fn create_used_variable(&self);
+    /// Declares the extern "C" main function for the entry point. Returns None if the symbol already exists.
+    fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function>;
 }
diff --git a/compiler/rustc_codegen_ssa/src/traits/mod.rs b/compiler/rustc_codegen_ssa/src/traits/mod.rs
index 0ac519dd0b1..698ef6083e6 100644
--- a/compiler/rustc_codegen_ssa/src/traits/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/mod.rs
@@ -35,7 +35,7 @@ pub use self::builder::{BuilderMethods, OverflowOp};
 pub use self::consts::ConstMethods;
 pub use self::coverageinfo::{CoverageInfoBuilderMethods, CoverageInfoMethods};
 pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods};
-pub use self::declare::{DeclareMethods, PreDefineMethods};
+pub use self::declare::PreDefineMethods;
 pub use self::intrinsic::IntrinsicCallMethods;
 pub use self::misc::MiscMethods;
 pub use self::statics::{StaticBuilderMethods, StaticMethods};
@@ -60,7 +60,6 @@ pub trait CodegenMethods<'tcx>:
     + StaticMethods
     + CoverageInfoMethods
     + DebugInfoMethods<'tcx>
-    + DeclareMethods<'tcx>
     + AsmMethods
     + PreDefineMethods<'tcx>
     + HasParamEnv<'tcx>
@@ -77,7 +76,6 @@ impl<'tcx, T> CodegenMethods<'tcx> for T where
         + StaticMethods
         + CoverageInfoMethods
         + DebugInfoMethods<'tcx>
-        + DeclareMethods<'tcx>
         + AsmMethods
         + PreDefineMethods<'tcx>
         + HasParamEnv<'tcx>