selfhost: add @[Drop] attribute for user-defined structs
- ast.bux: add isDrop field to Decl - parser.bux: parse @[Drop] attribute and attach to struct Decls - hir_lower.bux: auto-drop now looks for TypeName_Drop for any type - Test: _test_drop_user verifies Buffer_Drop is auto-called
This commit is contained in:
@@ -274,6 +274,7 @@ struct Decl {
|
||||
isPublic: bool,
|
||||
isAsync: bool,
|
||||
isChecked: int, // @[Checked] attribute (0/1)
|
||||
isDrop: int, // @[Drop] attribute (0/1)
|
||||
// Names
|
||||
strValue: String, // decl name
|
||||
strValue2: String, // interface name, dll name, module path
|
||||
|
||||
@@ -2164,6 +2164,12 @@ func Lcx_BuildAutoDropFree(ctx: *LowerCtx, typeName: String) -> String {
|
||||
return String_Concat(String_Concat("Map_Drop_", kType), String_Concat("_", vType));
|
||||
}
|
||||
}
|
||||
// User-defined types with @[Drop]: look for TypeName_Drop function
|
||||
let dropName: String = String_Concat(typeName, "_Drop");
|
||||
let dropSym: Symbol = Scope_Lookup(ctx.scope, dropName);
|
||||
if dropSym.decl != null as *Decl {
|
||||
return dropName;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
+10
-2
@@ -1570,8 +1570,9 @@ func parserParseDecl(p: *Parser) -> *Decl {
|
||||
}
|
||||
let isPublic: bool = parserMatch(p, tkPub);
|
||||
|
||||
// Parse @[Checked] attribute
|
||||
// Parse @[Checked] / @[Drop] attribute
|
||||
var isChecked: int = 0;
|
||||
var isDrop: int = 0;
|
||||
if parserCheck(p, tkAt) {
|
||||
discard parserAdvance(p); // @
|
||||
if parserCheck(p, tkLBracket) {
|
||||
@@ -1581,6 +1582,9 @@ func parserParseDecl(p: *Parser) -> *Decl {
|
||||
if String_Eq(attrName.text, "Checked") {
|
||||
isChecked = 1;
|
||||
}
|
||||
if String_Eq(attrName.text, "Drop") {
|
||||
isDrop = 1;
|
||||
}
|
||||
discard parserAdvance(p); // attribute name
|
||||
}
|
||||
if parserCheck(p, tkRBracket) {
|
||||
@@ -1606,7 +1610,11 @@ func parserParseDecl(p: *Parser) -> *Decl {
|
||||
d.isChecked = isChecked;
|
||||
return d;
|
||||
}
|
||||
if kind == tkStruct { return parserParseStructDecl(p, isPublic); }
|
||||
if kind == tkStruct {
|
||||
let d: *Decl = parserParseStructDecl(p, isPublic);
|
||||
d.isDrop = isDrop;
|
||||
return d;
|
||||
}
|
||||
if kind == tkEnum { return parserParseEnumDecl(p, isPublic); }
|
||||
if kind == tkImport { return parserParseImportDecl(p, isPublic); }
|
||||
if kind == tkExtern { return parserParseExternDecl(p, isPublic); }
|
||||
|
||||
Reference in New Issue
Block a user