early suggestion of -fcompound-names
diff --git a/libasn1compiler/asn1c_naming.c b/libasn1compiler/asn1c_naming.c
index 6ab3c4a..e408e55 100644
--- a/libasn1compiler/asn1c_naming.c
+++ b/libasn1compiler/asn1c_naming.c
@@ -4,6 +4,68 @@
#include "asn1c_misc.h"
#include <asn1_buffer.h>
+struct intl_name {
+ asn1p_expr_t *expr;
+ asn1p_expr_t *clashes_with;
+ const char *name;
+ TQ_ENTRY(struct intl_name) next;
+};
+static TQ_HEAD(struct intl_name) used_names;
+
+void
+c_name_clash_finder_init() {
+ TQ_INIT(&used_names);
+}
+
+static void
+register_global_name(arg_t *arg, const char *name) {
+ struct intl_name *n;
+
+ TQ_FOR(n, &used_names, next) {
+ if(strcmp(n->name, name) == 0) {
+ if(!(arg->expr->_mark & TM_NAMEGIVEN) && arg->expr != n->expr) {
+ n->clashes_with = arg->expr;
+ return;
+ }
+ }
+ }
+
+ n = calloc(1, sizeof(*n));
+ assert(n);
+ n->expr = arg->expr;
+ n->name = strdup(name);
+ TQ_ADD(&used_names, n, next);
+}
+
+int
+c_name_clash(arg_t *arg) {
+ struct intl_name *n;
+ size_t n_clashes = 0;
+ const size_t max_clashes = 5;
+
+ TQ_FOR(n, &used_names, next) {
+ if(n->clashes_with) {
+ if(n_clashes++ > max_clashes) continue;
+ FATAL(
+ "Name \"%s\" is generated by %s.%s at line %s:%d and "
+ "%s.%s at line %s:%d",
+ n->name, n->expr->module->ModuleName, n->expr->Identifier,
+ n->expr->module->source_file_name, n->expr->_lineno,
+ n->clashes_with->module->ModuleName,
+ n->clashes_with->Identifier,
+ n->clashes_with->module->source_file_name,
+ n->clashes_with->_lineno);
+ }
+ }
+
+ if(n_clashes > max_clashes) {
+ FATAL("... %zu more name clashes not shown", n_clashes - max_clashes);
+ }
+
+ return n_clashes > 0;
+}
+
+
static abuf *
construct_base_name(abuf *buf, arg_t *arg, int compound_names,
int avoid_keywords) {
@@ -97,6 +159,16 @@
abuf_free(part_name);
abuf_free(member_name);
+ /* A _subset_ of names is checked against being globally unique */
+ register_global_name(arg, names.base_name);
+ register_global_name(arg, names.full_name);
+ register_global_name(arg, names.presence_enum);
+ register_global_name(arg, names.presence_name);
+ register_global_name(arg, names.members_enum);
+ register_global_name(arg, names.members_name);
+
+ arg->expr->_mark |= TM_NAMEGIVEN;
+
return names;
}
@@ -133,5 +205,3 @@
return ab.buffer;
}
-
-
diff --git a/libasn1compiler/asn1c_naming.h b/libasn1compiler/asn1c_naming.h
index 2e0e88d..737f133 100644
--- a/libasn1compiler/asn1c_naming.h
+++ b/libasn1compiler/asn1c_naming.h
@@ -16,4 +16,13 @@
const char *c_member_name(arg_t *, asn1p_expr_t *); /* %s_%s */
const char *c_presence_name(arg_t *, asn1p_expr_t *); /* %s_PR_%s */
+/*
+ * Returns 0 if no C name clashes have been encountered.
+ * Returns 1 if C name clashes have been encountered.
+ * Prints out the clashing items and suggests -fcompound-names.
+ */
+int c_name_clash(arg_t *arg);
+
+void c_name_clash_finder_init(void);
+
#endif /* ASN1_COMPILER_NAMING_H */
diff --git a/libasn1compiler/asn1compiler.c b/libasn1compiler/asn1compiler.c
index de09cfb..8d963ef 100644
--- a/libasn1compiler/asn1compiler.c
+++ b/libasn1compiler/asn1compiler.c
@@ -3,6 +3,7 @@
#include "asn1c_out.h"
#include "asn1c_save.h"
#include "asn1c_ioc.h"
+#include "asn1c_naming.h"
static void default_logger_cb(int, const char *fmt, ...);
static int asn1c_compile_expr(arg_t *arg, const asn1c_ioc_table_and_objset_t *);
@@ -17,6 +18,8 @@
asn1p_module_t *mod;
int ret;
+ c_name_clash_finder_init();
+
/*
* Initialize target language.
*/
@@ -60,6 +63,20 @@
}
}
+ if(c_name_clash(arg)) {
+ if(arg->flags & A1C_COMPOUND_NAMES) {
+ FATAL("Name clashes encountered even with -fcompound-names flag");
+ /* Proceed further for better debugging. */
+ } else {
+ FATAL("Use \"-fcompound-names\" flag to asn1c to resolve name clashes");
+ if(arg->flags & A1C_PRINT_COMPILED) {
+ /* Proceed further for better debugging. */
+ } else {
+ return -1;
+ }
+ }
+ }
+
DEBUG("Saving compiled data");
/*