Hello,

> I guess that patch is two patches actually, one for the feature and
> one to obfuscate tcctok.h a little bit plus adding a new file to the
> project with some cryptic name plus showing a rather sophisticated
> method to count tokens to everybody.

s/not great/horrible/g; Yes, that's exactly what I meant, sorry about that.

>  So, would you think we can avoid the unnecessary and let tcctok.h stay
> as is, at least for now?  And approach the feature in a somehow less
> spectacular way, such as with: [...]?

Sure, I was trying to reduce the code duplication a bit, but probably
simpler and less verbose code is better. I have attached a modified
version of the patch with your suggested changes.
diff --git a/tccpp.c b/tccpp.c
index 897ef15..ad87cf0 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -93,6 +93,12 @@ static const unsigned char tok_two_chars[] =
     0
 };
 
+static int supported_arr[4][2] = {
+    SUPPORTED_ATTRIBUTES, SUPPORTED_BUILTINS,
+    /* We have only one profile, so __has_extension == __has_feature */
+    SUPPORTED_FEATURES, SUPPORTED_FEATURES
+};
+
 static void next_nomacro(void);
 
 ST_FUNC void skip(int c)
@@ -1410,6 +1416,23 @@ ST_FUNC void free_defines(Sym *b)
     }
 }
 
+ST_INLN int supported_check(int t, int type)
+{
+    int* arr = supported_arr[type];
+
+    if (t >= arr[0] && t <= arr[0] + arr[1])
+    {
+        return 1;
+    }
+    return 0;
+}
+
+ST_INLN int defined_check(int t)
+{
+    /* Ignore __has_include because it's a dummy implementation */
+    return !!define_find(t) || (t >= TOK___HAS_ATTRIBUTE && t <= TOK___HAS_FEATURE);
+}
+
 /* label lookup */
 ST_FUNC Sym *label_find(int v)
 {
@@ -1502,7 +1525,7 @@ static int expr_preprocess(void)
                 expect("identifier");
             if (tcc_state->run_test)
                 maybe_run_test(tcc_state);
-            c = define_find(tok) != 0;
+            c = defined_check(tok);
             if (t == '(') {
                 next_nomacro();
                 if (tok != ')')
@@ -1510,7 +1533,7 @@ static int expr_preprocess(void)
             }
             tok = TOK_CINT;
             tokc.i = c;
-        } else if (1 && tok == TOK___HAS_INCLUDE) {
+        } else if (tok == TOK___HAS_INCLUDE) {
             next();  /* XXX check if correct to use expansion */
             skip('(');
             while (tok != ')' && tok != TOK_EOF)
@@ -1519,6 +1542,18 @@ static int expr_preprocess(void)
               expect("')'");
             tok = TOK_CINT;
             tokc.i = 0;
+        } else if (tok >= TOK___HAS_ATTRIBUTE && tok <= TOK___HAS_FEATURE) {
+            t = tok;
+            next();
+            skip('(');
+            if (tok < TOK_IDENT)
+                expect("identifier");
+            c = supported_check(tok, t - TOK___HAS_ATTRIBUTE);
+            next();
+            if (tok != ')')
+              expect("')'");
+            tok = TOK_CINT;
+            tokc.i = c;
         } else if (tok >= TOK_IDENT) {
             /* if undefined macro, replace with zero, check for func-like */
             t = tok;
@@ -1965,7 +2000,7 @@ include_done:
                 file->ifndef_macro = tok;
             }
         }
-        c = (define_find(tok) != 0) ^ c;
+        c = defined_check(tok) ^ c;
     do_if:
         if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
             tcc_error("memory full (ifdef)");
diff --git a/tcctok.h b/tcctok.h
index d4c1ef5..1b89868 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -93,6 +93,10 @@
      DEF(TOK___FUNCTION__, "__FUNCTION__")
      DEF(TOK___VA_ARGS__, "__VA_ARGS__")
      DEF(TOK___COUNTER__, "__COUNTER__")
+     DEF(TOK___HAS_ATTRIBUTE, "__has_attribute")
+     DEF(TOK___HAS_BUILTIN, "__has_builtin")
+     DEF(TOK___HAS_FEATURE, "__has_feature")
+     DEF(TOK___HAS_EXTENSION, "__has_extension")
      DEF(TOK___HAS_INCLUDE, "__has_include")
 
 /* special identifiers */
@@ -109,6 +113,7 @@
 
 /* attribute identifiers */
 /* XXX: handle all tokens generically since speed is not critical */
+#define SUPPORTED_ATTRIBUTES {TOK_SECTION1, TOK_MODE}
      DEF(TOK_SECTION1, "section")
      DEF(TOK_SECTION2, "__section__")
      DEF(TOK_ALIGNED1, "aligned")
@@ -157,6 +162,7 @@
      DEF(TOK_VISIBILITY1, "visibility")
      DEF(TOK_VISIBILITY2, "__visibility__")
 
+#define SUPPORTED_BUILTINS {TOK_builtin_types_compatible_p, LAST_BUILTIN}
      DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
      DEF(TOK_builtin_choose_expr, "__builtin_choose_expr")
      DEF(TOK_builtin_constant_p, "__builtin_constant_p")
@@ -164,17 +170,27 @@
      DEF(TOK_builtin_return_address, "__builtin_return_address")
      DEF(TOK_builtin_expect, "__builtin_expect")
      /*DEF(TOK_builtin_va_list, "__builtin_va_list")*/
+#define LAST_BUILTIN TOK_builtin_va_start
 #if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
      DEF(TOK_builtin_va_start, "__builtin_va_start")
 #elif defined TCC_TARGET_X86_64
+#undef LAST_BUILTIN
+#define LAST_BUILTIN TOK_builtin_va_arg_types
      DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types")
 #elif defined TCC_TARGET_ARM64
-     DEF(TOK_builtin_va_start, "__builtin_va_start")
      DEF(TOK_builtin_va_arg, "__builtin_va_arg")
+     DEF(TOK_builtin_va_start, "__builtin_va_start")
 #elif defined TCC_TARGET_RISCV64
      DEF(TOK_builtin_va_start, "__builtin_va_start")
 #endif
 
+#define SUPPORTED_FEATURES {TOK_c_alignas, TOK_c_static_assert}
+     DEF(TOK_c_alignas, "c_alignas")
+     DEF(TOK_c_alignof, "c_alignof")
+     DEF(TOK_c_atomic, "c_atomic")
+     DEF(TOK_c_generic_selections, "c_generic_selections")
+     DEF(TOK_c_static_assert, "c_static_assert")
+
 /* atomic operations */
 #define DEF_ATOMIC(ID) DEF(TOK_##__##ID, "__"#ID)
      DEF_ATOMIC(atomic_store)
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to