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,
|
isPublic: bool,
|
||||||
isAsync: bool,
|
isAsync: bool,
|
||||||
isChecked: int, // @[Checked] attribute (0/1)
|
isChecked: int, // @[Checked] attribute (0/1)
|
||||||
|
isDrop: int, // @[Drop] attribute (0/1)
|
||||||
// Names
|
// Names
|
||||||
strValue: String, // decl name
|
strValue: String, // decl name
|
||||||
strValue2: String, // interface name, dll name, module path
|
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));
|
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 "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-2
@@ -1570,8 +1570,9 @@ func parserParseDecl(p: *Parser) -> *Decl {
|
|||||||
}
|
}
|
||||||
let isPublic: bool = parserMatch(p, tkPub);
|
let isPublic: bool = parserMatch(p, tkPub);
|
||||||
|
|
||||||
// Parse @[Checked] attribute
|
// Parse @[Checked] / @[Drop] attribute
|
||||||
var isChecked: int = 0;
|
var isChecked: int = 0;
|
||||||
|
var isDrop: int = 0;
|
||||||
if parserCheck(p, tkAt) {
|
if parserCheck(p, tkAt) {
|
||||||
discard parserAdvance(p); // @
|
discard parserAdvance(p); // @
|
||||||
if parserCheck(p, tkLBracket) {
|
if parserCheck(p, tkLBracket) {
|
||||||
@@ -1581,6 +1582,9 @@ func parserParseDecl(p: *Parser) -> *Decl {
|
|||||||
if String_Eq(attrName.text, "Checked") {
|
if String_Eq(attrName.text, "Checked") {
|
||||||
isChecked = 1;
|
isChecked = 1;
|
||||||
}
|
}
|
||||||
|
if String_Eq(attrName.text, "Drop") {
|
||||||
|
isDrop = 1;
|
||||||
|
}
|
||||||
discard parserAdvance(p); // attribute name
|
discard parserAdvance(p); // attribute name
|
||||||
}
|
}
|
||||||
if parserCheck(p, tkRBracket) {
|
if parserCheck(p, tkRBracket) {
|
||||||
@@ -1606,7 +1610,11 @@ func parserParseDecl(p: *Parser) -> *Decl {
|
|||||||
d.isChecked = isChecked;
|
d.isChecked = isChecked;
|
||||||
return d;
|
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 == tkEnum { return parserParseEnumDecl(p, isPublic); }
|
||||||
if kind == tkImport { return parserParseImportDecl(p, isPublic); }
|
if kind == tkImport { return parserParseImportDecl(p, isPublic); }
|
||||||
if kind == tkExtern { return parserParseExternDecl(p, isPublic); }
|
if kind == tkExtern { return parserParseExternDecl(p, isPublic); }
|
||||||
|
|||||||
Reference in New Issue
Block a user