diff --git a/src/ast.bux b/src/ast.bux index cd4db1a..25bf60e 100644 --- a/src/ast.bux +++ b/src/ast.bux @@ -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 diff --git a/src/hir_lower.bux b/src/hir_lower.bux index 812a927..488cfcb 100644 --- a/src/hir_lower.bux +++ b/src/hir_lower.bux @@ -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 ""; } diff --git a/src/parser.bux b/src/parser.bux index 236ce18..db1c3a5 100644 --- a/src/parser.bux +++ b/src/parser.bux @@ -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); }