Fix abstract array handling
[babeltrace.git] / formats / ctf / metadata / ctf-visitor-semantic-validator.c
index 6385b0bd3ffb2e76c61f3abe059083a8d53cd871..b89f7bd7660d0d363faf4dab4dd77d009bb57320 100644 (file)
@@ -24,6 +24,7 @@
 #include <glib.h>
 #include <inttypes.h>
 #include <errno.h>
+#include <babeltrace/babeltrace.h>
 #include <babeltrace/list.h>
 #include "ctf-scanner.h"
 #include "ctf-parser.h"
@@ -69,14 +70,28 @@ int ctf_visitor_unary_expression(FILE *fd, int depth, struct ctf_node *node)
                 * We are the length of a type declarator.
                 */
                switch (node->u.unary_expression.type) {
-               case UNARY_SIGNED_CONSTANT:
                case UNARY_UNSIGNED_CONSTANT:
+               case UNARY_STRING:
                        break;
                default:
-                       fprintf(fd, "[error]: semantic error (children of type declarator and enum can only be numeric constants)\n");
+                       fprintf(fd, "[error]: semantic error (children of type declarator and enum can only be unsigned numeric constants or references to fields (a.b.c))\n");
                        goto errperm;
                }
                break;                  /* OK */
+
+       case NODE_STRUCT:
+               /*
+                * We are the size of a struct align attribute.
+                */
+               switch (node->u.unary_expression.type) {
+               case UNARY_UNSIGNED_CONSTANT:
+                       break;
+               default:
+                       fprintf(fd, "[error]: semantic error (structure alignment attribute can only be unsigned numeric constants)\n");
+                       goto errperm;
+               }
+               break;
+
        case NODE_ENUMERATOR:
                /* The enumerator's parent has validated its validity already. */
                break;                  /* OK */
@@ -105,7 +120,6 @@ int ctf_visitor_unary_expression(FILE *fd, int depth, struct ctf_node *node)
        case NODE_ENUM:
        case NODE_STRUCT_OR_VARIANT_DECLARATION:
        case NODE_VARIANT:
-       case NODE_STRUCT:
        default:
                goto errinval;
        }
@@ -287,18 +301,21 @@ int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node)
                 */
                if (node->u.type_declarator.type == TYPEDEC_NESTED)
                        goto errperm;
-               switch (node->u.type_declarator.type) {
-               case TYPESPEC_FLOATING_POINT:
-               case TYPESPEC_INTEGER:
-               case TYPESPEC_STRING:
-               case TYPESPEC_STRUCT:
-               case TYPESPEC_VARIANT:
-               case TYPESPEC_ENUM:
-                       if (cds_list_empty(&node->u.type_declarator.pointers))
-                               goto errperm;
-                       break;
-               default:
-                       break;
+               cds_list_for_each_entry(iter, &node->parent->u.typealias_alias.type_specifier_list->u.type_specifier_list.head,
+                                       siblings) {
+                       switch (iter->u.type_specifier.type) {
+                       case TYPESPEC_FLOATING_POINT:
+                       case TYPESPEC_INTEGER:
+                       case TYPESPEC_STRING:
+                       case TYPESPEC_STRUCT:
+                       case TYPESPEC_VARIANT:
+                       case TYPESPEC_ENUM:
+                               if (cds_list_empty(&node->u.type_declarator.pointers))
+                                       goto errperm;
+                               break;
+                       default:
+                               break;
+                       }
                }
                if (node->u.type_declarator.type == TYPEDEC_ID &&
                    node->u.type_declarator.u.id != NULL)
@@ -328,13 +345,11 @@ int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node)
                goto errinval;
        }
 
-       if (!cds_list_empty(&node->u.type_declarator.pointers)) {
-               cds_list_for_each_entry(iter, &node->u.type_declarator.pointers,
-                                       siblings) {
-                       ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
-                       if (ret)
-                               return ret;
-               }
+       cds_list_for_each_entry(iter, &node->u.type_declarator.pointers,
+                               siblings) {
+               ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
+               if (ret)
+                       return ret;
        }
 
        switch (node->u.type_declarator.type) {
@@ -348,10 +363,23 @@ int ctf_visitor_type_declarator(FILE *fd, int depth, struct ctf_node *node)
                        if (ret)
                                return ret;
                }
-               ret = _ctf_visitor_semantic_check(fd, depth + 1,
-                       node->u.type_declarator.u.nested.length);
-               if (ret)
-                       return ret;
+               if (!node->u.type_declarator.u.nested.abstract_array) {
+                       cds_list_for_each_entry(iter, &node->u.type_declarator.u.nested.length,
+                                               siblings) {
+                               if (iter->type != NODE_UNARY_EXPRESSION) {
+                                       fprintf(fd, "[error] %s: expecting unary expression as length\n", __func__);
+                                       return -EINVAL;
+                               }
+                               ret = _ctf_visitor_semantic_check(fd, depth + 1, iter);
+                               if (ret)
+                                       return ret;
+                       }
+               } else {
+                       if (node->parent->type == NODE_TYPEALIAS_TARGET) {
+                               fprintf(fd, "[error] %s: abstract array declarator not permitted as target of typealias\n", __func__);
+                               return -EINVAL;
+                       }
+               }
                if (node->u.type_declarator.bitfield_len) {
                        ret = _ctf_visitor_semantic_check(fd, depth + 1,
                                node->u.type_declarator.bitfield_len);
@@ -862,15 +890,15 @@ int ctf_visitor_semantic_check(FILE *fd, int depth, struct ctf_node *node)
         * take the safe route and recreate them at each validation, just in
         * case the structure has changed.
         */
-       fprintf(fd, "CTF visitor: parent links creation... ");
+       printf_verbose("CTF visitor: parent links creation... ");
        ret = ctf_visitor_parent_links(fd, depth, node);
        if (ret)
                return ret;
-       fprintf(fd, "done.\n");
-       fprintf(fd, "CTF visitor: semantic check... ");
+       printf_verbose("done.\n");
+       printf_verbose("CTF visitor: semantic check... ");
        ret = _ctf_visitor_semantic_check(fd, depth, node);
        if (ret)
                return ret;
-       fprintf(fd, "done.\n");
+       printf_verbose("done.\n");
        return ret;
 }
This page took 0.024516 seconds and 4 git commands to generate.