0

I'm writing a GCC plugin and would like to identify typedef and using.

plugin.cpp

#include <gcc-plugin.h>
#include <tree.h>
#include <tree-pretty-print.h>
#include <plugin-version.h>
#include <c-family/c-common.h>

#include <iostream>

int plugin_is_GPL_compatible;

static const std::string tree_code_str(enum tree_code code)
{
    std::string str {get_tree_code_name(code)};
    str += " (" + std::to_string(code) + ")";
    return str;
}

static const char* get_tree_name(tree t) {
    if (t == NULL_TREE) {
        return "<null>";
    }

    const char *name = get_name(t);
    if (name) {
        return name;
    }

    return "<no name>";
}

static const char* get_type_name_str(tree var_type)
{
    const char *type_name = NULL;
    if (TYPE_NAME(var_type) != NULL_TREE) {
        tree type_name_tree = TYPE_NAME(var_type);
        if (TREE_CODE(type_name_tree) == TYPE_DECL) {
            type_name = IDENTIFIER_POINTER(DECL_NAME(type_name_tree));
        } else if (TREE_CODE(type_name_tree) == IDENTIFIER_NODE) {
            type_name = IDENTIFIER_POINTER(type_name_tree);
        }
    }

    if (type_name) {
        return type_name;
    } else {
        return "<no type name>";
    }
}

static void plugin_finish_decl(void *gcc_data, void *user_data) {
    tree decl = (tree) gcc_data;
    std::cout << "TREE_CODE=[" << tree_code_str(TREE_CODE(decl)) << "] "
              << "TREE_TYPE=[" << get_type_name_str(TREE_TYPE(decl)) << "] "
              << "TREE_CODE(TREE_TYPE)=[" << tree_code_str(TREE_CODE(TREE_TYPE(decl))) << "] "
              << "TREE_CODE(TYPE_NAME)=[" << tree_code_str(TREE_CODE(TYPE_NAME(decl))) << "] "
              << "name=[" << get_tree_name(decl) << "] "
              << std::endl;
}

int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) {
    if (!plugin_default_version_check(version, &gcc_version)) {
        fprintf(stderr, "Incompatible GCC version\n");
        return 1;
    }

    register_callback(plugin_info->base_name, PLUGIN_FINISH_DECL, plugin_finish_decl, NULL);

    return 0;
}

test.cpp

typedef int MyInt;
MyInt var {};
int main() { return 0; }

output

TREE_CODE=[var_decl (36)] TREE_TYPE=[MyInt] TREE_CODE(TREE_TYPE)=[integer_type (8)] TREE_CODE(TYPE_NAME)=[identifier_node (1)] name=[var]

As we can see from the output, MyInt is of type integer and not TYPE_DECL. GCC Documentation

I tried with GCC version 10 and 13. The result is the same.

Do you have an explanation? The GCC documentation doesn't seem clear on this point?

4
  • 2
    I'm not sure where you are gong with this question. Are you looking for a way to distinguish an alias made with typedef from an alias made with using? Commented Jan 21 at 20:49
  • 4
    typedef and using are just aliases for existing types, they don't create new types. The actual type of MyInt is int. Commented Jan 21 at 20:57
  • 1
    You expected the type to be... what? MyInt? Commented Jan 21 at 21:22
  • Sorry, I forgot to say what I expected. TREE_CODE(TREE_TYPE)=[type_decl] like link Commented Jan 21 at 21:28

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.