Add Definition kind for asm register classes

This commit is contained in:
Lukas Wirth 2024-09-05 10:23:00 +02:00
parent 1328b52e91
commit 44e3b7d205
16 changed files with 214 additions and 28 deletions

View File

@ -1413,7 +1413,7 @@ fn asm_unit() {
r#"
//- minicore: asm
fn unit() {
asm!("")
core::arch::asm!("")
}
"#,
);
@ -1425,7 +1425,7 @@ fn asm_no_return() {
r#"
//- minicore: asm
fn unit() -> ! {
asm!("", options(noreturn))
core::arch::asm!("", options(noreturn))
}
"#,
);
@ -1440,7 +1440,7 @@ fn main() {
unsafe {
let foo = 1;
let mut o = 0;
asm!(
core::arch::asm!(
"%input = OpLoad _ {0}",
concat!("%result = ", bar, " _ %input"),
"OpStore {1} %result",
@ -1450,7 +1450,7 @@ fn main() {
o
let thread_id: usize;
asm!("
core::arch::asm!("
mov {0}, gs:[0x30]
mov {0}, [{0}+0x48]
", out(reg) thread_id, options(pure, readonly, nostack));
@ -1460,7 +1460,7 @@ fn main() {
static VirtualFree: usize;
const OffPtr: usize;
const OffFn: usize;
asm!("
core::arch::asm!("
push {free_type}
push {free_size}
push {base}
@ -1490,16 +1490,16 @@ fn main() {
"#,
expect![[r#"
!0..122 'builti...muto,)': ()
!0..190 'builti...tack))': ()
!0..136 'builti...tack))': ()
!0..449 'builti...urn),)': !
10..1254 '{ ... } }': ()
16..1252 'unsafe... }': ()
10..1236 '{ ... } }': ()
16..1234 'unsafe... }': ()
37..40 'foo': i32
43..44 '1': i32
58..63 'mut o': i32
66..67 '0': i32
281..282 'o': i32
296..305 'thread_id': usize
293..294 'o': i32
308..317 'thread_id': usize
"#]],
)
}

View File

@ -360,6 +360,7 @@ pub(crate) fn tag(self) -> &'static str {
SymbolKind::Field => "fd",
SymbolKind::Function => "fn",
SymbolKind::Impl => "im",
SymbolKind::InlineAsmRegOrRegClass => "ar",
SymbolKind::Label => "lb",
SymbolKind::LifetimeParam => "lt",
SymbolKind::Local => "lc",

View File

@ -50,6 +50,7 @@ pub enum Definition {
BuiltinAttr(BuiltinAttr),
ToolModule(ToolModule),
ExternCrateDecl(ExternCrateDecl),
InlineAsmRegOrRegClass(()),
}
impl Definition {
@ -87,7 +88,8 @@ pub fn module(&self, db: &RootDatabase) -> Option<Module> {
| Definition::BuiltinType(_)
| Definition::BuiltinLifetime(_)
| Definition::TupleField(_)
| Definition::ToolModule(_) => return None,
| Definition::ToolModule(_)
| Definition::InlineAsmRegOrRegClass(_) => return None,
};
Some(module)
}
@ -121,7 +123,8 @@ pub fn visibility(&self, db: &RootDatabase) -> Option<Visibility> {
| Definition::Local(_)
| Definition::GenericParam(_)
| Definition::Label(_)
| Definition::DeriveHelper(_) => return None,
| Definition::DeriveHelper(_)
| Definition::InlineAsmRegOrRegClass(_) => return None,
};
Some(vis)
}
@ -150,6 +153,7 @@ pub fn name(&self, db: &RootDatabase) -> Option<Name> {
Definition::ToolModule(_) => return None, // FIXME
Definition::DeriveHelper(it) => it.name(db),
Definition::ExternCrateDecl(it) => return it.alias_or_name(db),
Definition::InlineAsmRegOrRegClass(_) => return None, // FIXME
};
Some(name)
}
@ -212,6 +216,7 @@ pub fn docs(
Definition::ToolModule(_) => None,
Definition::DeriveHelper(_) => None,
Definition::TupleField(_) => None,
Definition::InlineAsmRegOrRegClass(_) => None,
};
docs.or_else(|| {
@ -268,6 +273,8 @@ pub fn label(&self, db: &RootDatabase, edition: Edition) -> String {
Definition::DeriveHelper(it) => {
format!("derive_helper {}", it.name(db).display(db, edition))
}
// FIXME
Definition::InlineAsmRegOrRegClass(_) => "inline_asm_reg_or_reg_class".to_owned(),
}
}
}

View File

@ -224,6 +224,7 @@ pub enum SymbolKind {
Function,
Method,
Impl,
InlineAsmRegOrRegClass,
Label,
LifetimeParam,
Local,

View File

@ -205,7 +205,8 @@ pub fn range_for_rename(self, sema: &Semantics<'_, RootDatabase>) -> Option<File
| Definition::BuiltinAttr(_)
| Definition::SelfType(_)
| Definition::ToolModule(_)
| Definition::TupleField(_) => return None,
| Definition::TupleField(_)
| Definition::InlineAsmRegOrRegClass(_) => return None,
// FIXME: This should be doable in theory
Definition::DeriveHelper(_) => return None,
};

View File

@ -219,7 +219,8 @@ pub(crate) fn resolve_doc_path_for_def(
| Definition::Local(_)
| Definition::GenericParam(_)
| Definition::Label(_)
| Definition::DeriveHelper(_) => None,
| Definition::DeriveHelper(_)
| Definition::InlineAsmRegOrRegClass(_) => None,
}
.map(Definition::from)
}
@ -672,7 +673,8 @@ fn filename_and_frag_for_def(
| Definition::BuiltinAttr(_)
| Definition::BuiltinLifetime(_)
| Definition::ToolModule(_)
| Definition::DeriveHelper(_) => return None,
| Definition::DeriveHelper(_)
| Definition::InlineAsmRegOrRegClass(_) => return None,
};
Some((def, res, None))

View File

@ -228,6 +228,7 @@ pub(crate) fn def_to_kind(db: &RootDatabase, def: Definition) -> SymbolInformati
Definition::BuiltinAttr(..) => Attribute,
Definition::ToolModule(..) => Module,
Definition::ExternCrateDecl(..) => Module,
Definition::InlineAsmRegOrRegClass(..) => Module,
}
}
@ -320,7 +321,8 @@ pub(crate) fn def_to_moniker(
| Definition::DeriveHelper(_)
| Definition::BuiltinLifetime(_)
| Definition::BuiltinAttr(_)
| Definition::ToolModule(_) => return None,
| Definition::ToolModule(_)
| Definition::InlineAsmRegOrRegClass(_) => return None,
Definition::Local(local) => {
if !local.is_param(db) {

View File

@ -242,6 +242,7 @@ fn try_to_nav(&self, db: &RootDatabase) -> Option<UpmappingResult<NavigationTarg
| Definition::BuiltinType(_)
| Definition::TupleField(_)
| Definition::ToolModule(_)
| Definition::InlineAsmRegOrRegClass(_)
| Definition::BuiltinAttr(_) => None,
// FIXME: The focus range should be set to the helper declaration
Definition::DeriveHelper(it) => it.derive().try_to_nav(db),

View File

@ -534,6 +534,9 @@ pub(super) fn highlight_def(
Definition::BuiltinAttr(_) => Highlight::new(HlTag::Symbol(SymbolKind::BuiltinAttr)),
Definition::ToolModule(_) => Highlight::new(HlTag::Symbol(SymbolKind::ToolModule)),
Definition::DeriveHelper(_) => Highlight::new(HlTag::Symbol(SymbolKind::DeriveHelper)),
Definition::InlineAsmRegOrRegClass(_) => {
Highlight::new(HlTag::Symbol(SymbolKind::InlineAsmRegOrRegClass))
}
};
let def_crate = def.krate(db);

View File

@ -315,6 +315,7 @@ fn module_def_to_hl_tag(def: Definition) -> HlTag {
Definition::BuiltinAttr(_) => SymbolKind::BuiltinAttr,
Definition::ToolModule(_) => SymbolKind::ToolModule,
Definition::DeriveHelper(_) => SymbolKind::DeriveHelper,
Definition::InlineAsmRegOrRegClass(_) => SymbolKind::InlineAsmRegOrRegClass,
};
HlTag::Symbol(symbol)
}

View File

@ -146,6 +146,7 @@ fn as_str(self) -> &'static str {
SymbolKind::Field => "field",
SymbolKind::Function => "function",
SymbolKind::Impl => "self_type",
SymbolKind::InlineAsmRegOrRegClass => "reg",
SymbolKind::Label => "label",
SymbolKind::LifetimeParam => "lifetime",
SymbolKind::Local => "variable",

View File

@ -0,0 +1,98 @@
<style>
body { margin: 0; }
pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
.lifetime { color: #DFAF8F; font-style: italic; }
.label { color: #DFAF8F; font-style: italic; }
.comment { color: #7F9F7F; }
.documentation { color: #629755; }
.intra_doc_link { font-style: italic; }
.injected { opacity: 0.65 ; }
.struct, .enum { color: #7CB8BB; }
.enum_variant { color: #BDE0F3; }
.string_literal { color: #CC9393; }
.field { color: #94BFF3; }
.function { color: #93E0E3; }
.function.unsafe { color: #BC8383; }
.trait.unsafe { color: #BC8383; }
.operator.unsafe { color: #BC8383; }
.mutable.unsafe { color: #BC8383; text-decoration: underline; }
.keyword.unsafe { color: #BC8383; font-weight: bold; }
.macro.unsafe { color: #BC8383; }
.parameter { color: #94BFF3; }
.text { color: #DCDCCC; }
.type { color: #7CB8BB; }
.builtin_type { color: #8CD0D3; }
.type_param { color: #DFAF8F; }
.attribute { color: #94BFF3; }
.numeric_literal { color: #BFEBBF; }
.bool_literal { color: #BFE6EB; }
.macro { color: #94BFF3; }
.proc_macro { color: #94BFF3; text-decoration: underline; }
.derive { color: #94BFF3; font-style: italic; }
.module { color: #AFD8AF; }
.value_param { color: #DCDCCC; }
.variable { color: #DCDCCC; }
.format_specifier { color: #CC696B; }
.mutable { text-decoration: underline; }
.escape_sequence { color: #94BFF3; }
.keyword { color: #F0DFAF; font-weight: bold; }
.control { font-style: italic; }
.reference { font-style: italic; font-weight: bold; }
.const { font-weight: bolder; }
.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
</style>
<pre><code><span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
<span class="keyword unsafe">unsafe</span> <span class="brace">{</span>
<span class="keyword">let</span> <span class="variable declaration">foo</span> <span class="operator">=</span> <span class="numeric_literal">1</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">o</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span>
<span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>
<span class="string_literal macro">"%input = OpLoad _ {0}"</span><span class="comma macro">,</span>
<span class="macro default_library library macro">concat</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"%result = "</span><span class="comma macro">,</span> <span class="unresolved_reference macro">bar</span><span class="comma macro">,</span> <span class="string_literal macro">" _ %input"</span><span class="parenthesis macro">)</span><span class="comma macro">,</span>
<span class="string_literal macro">"OpStore {1} %result"</span><span class="comma macro">,</span>
<span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="unresolved_reference macro">reg</span><span class="parenthesis macro">)</span> <span class="operator macro">&</span><span class="variable macro">foo</span><span class="comma macro">,</span>
<span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="unresolved_reference macro">reg</span><span class="parenthesis macro">)</span> <span class="operator macro">&</span><span class="keyword macro">mut</span> <span class="variable macro mutable">o</span><span class="comma macro">,</span>
<span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="variable mutable">o</span>
<span class="keyword">let</span> <span class="variable declaration">thread_id</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
<span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"
mov {0}, gs:[0x30]
mov {0}, [{0}+0x48]
"</span><span class="comma macro">,</span> <span class="keyword macro">out</span><span class="parenthesis macro">(</span><span class="unresolved_reference macro">reg</span><span class="parenthesis macro">)</span> <span class="variable macro">thread_id</span><span class="comma macro">,</span> <span class="keyword macro">options</span><span class="parenthesis macro">(</span><span class="keyword macro">pure</span><span class="comma macro">,</span> <span class="keyword macro">readonly</span><span class="comma macro">,</span> <span class="keyword macro">nostack</span><span class="parenthesis macro">)</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="keyword">static</span> <span class="static declaration">UNMAP_BASE</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
<span class="keyword const">const</span> <span class="constant const declaration">MEM_RELEASE</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
<span class="keyword">static</span> <span class="static declaration">VirtualFree</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
<span class="keyword const">const</span> <span class="constant const declaration">OffPtr</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
<span class="keyword const">const</span> <span class="constant const declaration">OffFn</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
<span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"
push {free_type}
push {free_size}
push {base}
mov eax, fs:[30h]
mov eax, [eax+8h]
add eax, {off_fn}
mov [eax-{off_fn}+{off_ptr}], eax
push eax
jmp {virtual_free}
"</span><span class="comma macro">,</span>
<span class="unresolved_reference declaration macro">off_ptr</span> <span class="operator macro">=</span> <span class="keyword macro">const</span> <span class="constant const macro">OffPtr</span><span class="comma macro">,</span>
<span class="unresolved_reference declaration macro">off_fn</span> <span class="operator macro">=</span> <span class="keyword macro">const</span> <span class="constant const macro">OffFn</span><span class="comma macro">,</span>
<span class="unresolved_reference declaration macro">free_size</span> <span class="operator macro">=</span> <span class="keyword macro">const</span> <span class="numeric_literal macro">0</span><span class="comma macro">,</span>
<span class="unresolved_reference declaration macro">free_type</span> <span class="operator macro">=</span> <span class="keyword macro">const</span> <span class="constant const macro">MEM_RELEASE</span><span class="comma macro">,</span>
<span class="unresolved_reference declaration macro">virtual_free</span> <span class="operator macro">=</span> <span class="keyword macro">sym</span> <span class="static macro">VirtualFree</span><span class="comma macro">,</span>
<span class="unresolved_reference declaration macro">base</span> <span class="operator macro">=</span> <span class="keyword macro">sym</span> <span class="static macro">UNMAP_BASE</span><span class="comma macro">,</span>
<span class="keyword macro">options</span><span class="parenthesis macro">(</span><span class="keyword macro">noreturn</span><span class="parenthesis macro">)</span><span class="comma macro">,</span>
<span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="brace">}</span>
<span class="brace">}</span></code></pre>

View File

@ -165,7 +165,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
<span class="macro">toho</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"{}fmt"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="variable declaration">i</span><span class="colon">:</span> <span class="builtin_type">u64</span> <span class="operator">=</span> <span class="numeric_literal">3</span><span class="semicolon">;</span>
<span class="keyword">let</span> <span class="variable declaration">o</span><span class="colon">:</span> <span class="builtin_type">u64</span><span class="semicolon">;</span>
<span class="macro default_library library">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>
<span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>
<span class="string_literal macro">"mov {0}, {1}"</span><span class="comma macro">,</span>
<span class="string_literal macro">"add {0}, 5"</span><span class="comma macro">,</span>
<span class="keyword macro">out</span><span class="parenthesis macro">(</span><span class="unresolved_reference macro">reg</span><span class="parenthesis macro">)</span> <span class="variable macro">o</span><span class="comma macro">,</span>

View File

@ -549,7 +549,7 @@ fn main() {
toho!("{}fmt", 0);
let i: u64 = 3;
let o: u64;
asm!(
core::arch::asm!(
"mov {0}, {1}",
"add {0}, 5",
out(reg) o,
@ -1275,3 +1275,65 @@ fn f<'de, T: Deserialize<'de>>() {
);
let _ = analysis.highlight(HL_CONFIG, file_id).unwrap();
}
#[test]
fn test_asm_highlighting() {
check_highlighting(
r#"
//- minicore: asm, concat
fn main() {
unsafe {
let foo = 1;
let mut o = 0;
core::arch::asm!(
"%input = OpLoad _ {0}",
concat!("%result = ", bar, " _ %input"),
"OpStore {1} %result",
in(reg) &foo,
in(reg) &mut o,
);
o
let thread_id: usize;
core::arch::asm!("
mov {0}, gs:[0x30]
mov {0}, [{0}+0x48]
", out(reg) thread_id, options(pure, readonly, nostack));
static UNMAP_BASE: usize;
const MEM_RELEASE: usize;
static VirtualFree: usize;
const OffPtr: usize;
const OffFn: usize;
core::arch::asm!("
push {free_type}
push {free_size}
push {base}
mov eax, fs:[30h]
mov eax, [eax+8h]
add eax, {off_fn}
mov [eax-{off_fn}+{off_ptr}], eax
push eax
jmp {virtual_free}
",
off_ptr = const OffPtr,
off_fn = const OffFn,
free_size = const 0,
free_type = const MEM_RELEASE,
virtual_free = sym VirtualFree,
base = sym UNMAP_BASE,
options(noreturn),
);
}
}
"#,
expect_file!["./test_data/highlight_asm.html"],
false,
);
}

View File

@ -80,6 +80,7 @@ pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind {
| SymbolKind::ValueParam
| SymbolKind::Label => lsp_types::SymbolKind::VARIABLE,
SymbolKind::Union => lsp_types::SymbolKind::STRUCT,
SymbolKind::InlineAsmRegOrRegClass => lsp_types::SymbolKind::VARIABLE,
}
}
@ -159,6 +160,7 @@ pub(crate) fn completion_item_kind(
SymbolKind::Variant => lsp_types::CompletionItemKind::ENUM_MEMBER,
SymbolKind::BuiltinAttr => lsp_types::CompletionItemKind::FUNCTION,
SymbolKind::ToolModule => lsp_types::CompletionItemKind::MODULE,
SymbolKind::InlineAsmRegOrRegClass => lsp_types::CompletionItemKind::KEYWORD,
},
}
}
@ -702,6 +704,7 @@ fn semantic_token_type_and_modifiers(
SymbolKind::ProcMacro => types::PROC_MACRO,
SymbolKind::BuiltinAttr => types::BUILTIN_ATTRIBUTE,
SymbolKind::ToolModule => types::TOOL_MODULE,
SymbolKind::InlineAsmRegOrRegClass => types::KEYWORD,
},
HlTag::AttributeBracket => types::ATTRIBUTE_BRACKET,
HlTag::BoolLiteral => types::BOOLEAN,

View File

@ -1475,6 +1475,19 @@ pub const fn panic(expr: &'static str) -> ! {
}
// endregion:panic
// region:asm
mod arch {
#[rustc_builtin_macro]
pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */
}
#[rustc_builtin_macro]
pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */
}
}
// endregion:asm
#[macro_use]
mod macros {
// region:panic
@ -1487,16 +1500,6 @@ macro_rules! panic {
}
// endregion:panic
// region:asm
#[macro_export]
#[rustc_builtin_macro]
macro_rules! asm {
($($arg:tt)*) => {
/* compiler built-in */
};
}
// endregion:asm
// region:assert
#[macro_export]
#[rustc_builtin_macro]