]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - gmqcc.h
Fix #161
[xonotic/gmqcc.git] / gmqcc.h
diff --git a/gmqcc.h b/gmqcc.h
index 34fefaae5dec5e984cbfce56c0c02eaece80813a..4e3fb399eba42b7604ac7b76b413d6cd74ec8e92 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -1,6 +1,10 @@
 #ifndef GMQCC_HDR
 #define GMQCC_HDR
 #include <vector>
+#include <string>
+#include <utility>
+#include <memory>
+using std::move;
 #include <stdarg.h>
 #include <stddef.h>
 #include <stdlib.h>
@@ -227,7 +231,7 @@ void _util_vec_delete(void *vec);
 
 /* exposed interface */
 #define vec_meta(A)       ((vector_t*)(((char *)(A)) - sizeof(vector_t)))
-#define vec_free(A)       ((void)((A) ? (_util_vec_delete((void *)(A)), (A) = NULL) : 0))
+#define vec_free(A)       ((void)((A) ? (_util_vec_delete((void *)(A)), (A) = nullptr) : 0))
 #define vec_push(A,V)     (GMQCC_VEC_WILLGROW((A),1), (A)[vec_meta(A)->used++] = (V))
 #define vec_size(A)       ((A) ? vec_meta(A)->used : 0)
 #define vec_add(A,N)      (GMQCC_VEC_WILLGROW((A),(N)), vec_meta(A)->used += (N), &(A)[vec_meta(A)->used-(N)])
@@ -259,7 +263,7 @@ int util_getline(char  **, size_t *, FILE *);
 /* code.c */
 
 /* Note: if you change the order, fix type_sizeof in ir.c */
-enum {
+enum qc_type {
     TYPE_VOID     ,
     TYPE_STRING   ,
     TYPE_FLOAT    ,
@@ -498,6 +502,10 @@ typedef int32_t qcint_t;
 typedef uint32_t qcuint_t;
 
 struct code_t {
+    void* operator new(std::size_t);
+    void operator delete(void*);
+    code_t();
+    ~code_t();
     std::vector<prog_section_statement_t> statements;
     std::vector<int> linenums;
     std::vector<int> columnnums;
@@ -506,10 +514,10 @@ struct code_t {
     std::vector<prog_section_function_t> functions;
     std::vector<int> globals;
     std::vector<char> chars;
-    uint16_t crc;
-    uint32_t entfields;
+    uint16_t crc = 0;
+    uint32_t entfields = 0;
     ht string_cache;
-    qcint_t string_cached_empty;
+    qcint_t string_cached_empty = 0;
 };
 
 /*
@@ -581,15 +589,31 @@ extern size_t compile_errors;
 extern size_t compile_Werrors;
 extern size_t compile_warnings;
 
-void /********/ compile_error   (lex_ctx_t ctx, /*LVL_ERROR*/ const char *msg, ...);
+void /********/ compile_error_  (lex_ctx_t ctx, /*LVL_ERROR*/ const char *msg, ...);
 void /********/ vcompile_error  (lex_ctx_t ctx, /*LVL_ERROR*/ const char *msg, va_list ap);
-bool GMQCC_WARN compile_warning (lex_ctx_t ctx, int warntype, const char *fmt, ...);
+bool GMQCC_WARN compile_warning_(lex_ctx_t ctx, int warntype, const char *fmt, ...);
 bool GMQCC_WARN vcompile_warning(lex_ctx_t ctx, int warntype, const char *fmt, va_list ap);
 void            compile_show_werrors(void);
 
+template <typename T>
+inline constexpr const T formatNormalize(const T argument) { return argument; }
+
+inline const char *formatNormalize(const std::string &argument) {
+    return argument.c_str();
+}
+
+template<typename... Ts>
+inline bool GMQCC_WARN compile_warning(lex_ctx_t ctx, int warntype, const char *fmt, const Ts&... ts) {
+    return compile_warning_(ctx, warntype, fmt, formatNormalize(ts)...);
+}
+template<typename... Ts>
+inline void /********/ compile_error   (lex_ctx_t ctx, /*LVL_ERROR*/ const char *msg, const Ts&... ts) {
+    return compile_error_(ctx, msg, formatNormalize(ts)...);
+}
+
 /* ir.c */
 /* TODO: cleanup */
-enum store_types {
+enum store_type {
     store_global,
     store_local,  /* local, assignable for now, should get promoted later */
     store_param,  /* parameters, they are locals with a fixed position */