+static ExprNode* FuncAddrSize(void)
+/* Handle the .ADDRSIZE function */
+{
+ StrBuf ScopeName = STATIC_STRBUF_INITIALIZER;
+ StrBuf Name = STATIC_STRBUF_INITIALIZER;
+ SymEntry* Sym;
+ int AddrSize;
+ int NoScope;
+
+
+ /* Assume we don't know the size */
+ AddrSize = 0;
+
+ /* Check for a cheap local which needs special handling */
+ if (CurTok.Tok == TOK_LOCAL_IDENT) {
+
+ /* Cheap local symbol */
+ Sym = SymFindLocal(SymLast, &CurTok.SVal, SYM_FIND_EXISTING);
+ if (Sym == 0) {
+ Error("Unknown symbol or scope: `%m%p'", &CurTok.SVal);
+ }
+ else {
+ AddrSize = Sym->AddrSize;
+ }
+
+ /* Remember and skip SVal, terminate ScopeName so it is empty */
+ SB_Copy(&Name, &CurTok.SVal);
+ NextTok();
+ SB_Terminate(&ScopeName);
+
+ }
+ else {
+
+ /* Parse the scope and the name */
+ SymTable* ParentScope = ParseScopedIdent(&Name, &ScopeName);
+
+ /* Check if the parent scope is valid */
+ if (ParentScope == 0) {
+ /* No such scope */
+ SB_Done(&ScopeName);
+ SB_Done(&Name);
+ return GenLiteral0();
+ }
+
+ /* If ScopeName is empty, no explicit scope was specified. We have to
+ * search upper scope levels in this case.
+ */
+ NoScope = SB_IsEmpty(&ScopeName);
+
+ /* If we did find a scope with the name, read the symbol defining the
+ * size, otherwise search for a symbol entry with the name and scope.
+ */
+ if (NoScope) {
+ Sym = SymFindAny(ParentScope, &Name);
+ }
+ else {
+ Sym = SymFind(ParentScope, &Name, SYM_FIND_EXISTING);
+ }
+ /* If we found the symbol retrieve the size, otherwise complain */
+ if (Sym) {
+ AddrSize = Sym->AddrSize;
+ }
+ else {
+ Error("Unknown symbol or scope: `%m%p%m%p'",
+ &ScopeName, &Name);
+ }
+
+ }
+
+ /* Check if we have a size */
+ /* if we don't know, return it anyway, zero can mean unknown, or uncomment this code for an error
+ if (AddrSize == 0 ) {
+ Error ("Address size of `%m%p%m%p' is unknown", &ScopeName, &Name);
+ }
+ */
+
+ /* Free the string buffers */
+ SB_Done(&ScopeName);
+ SB_Done(&Name);
+
+ /* Return the size */
+ return GenLiteralExpr(AddrSize);
+}
+
+
+
static ExprNode* FuncSizeOf (void)
/* Handle the .SIZEOF function */
{
N = Function (FuncBankByte);
break;
+ case TOK_ADDRSIZE:
+ N = Function(FuncAddrSize);
+ break;
+
case TOK_BLANK:
N = Function (FuncBlank);
break;
{ ".A16", TOK_A16 },
{ ".A8", TOK_A8 },
{ ".ADDR", TOK_ADDR },
+ { ".ADDRSIZE", TOK_ADDRSIZE },
{ ".ALIGN", TOK_ALIGN },
{ ".AND", TOK_BOOLAND },
{ ".ASCIIZ", TOK_ASCIIZ },
R = bsearch (&K, DotKeywords, sizeof (DotKeywords) / sizeof (DotKeywords [0]),
sizeof (DotKeywords [0]), CmpDotKeyword);
if (R != 0) {
+
+ /* By default, disable any somewhat experiemental DotKeyword. */
+
+ switch (R->Tok) {
+
+ case TOK_ADDRSIZE:
+ /* Disallow .ADDRSIZE function by default */
+ if (AddrSize == 0) {
+ return TOK_NONE;
+ }
+ break;
+
+ default:
+ break;
+ }
return R->Tok;
- } else {
+ }
+ else {
return TOK_NONE;
}
}