#define DECL_P(CODE)\
(TREE_CODE_CLASS (TREE_CODE (CODE)) == tcc_declaration)
+/* Nonzero if CODE represents a memory tag. */
+
+#define MTAG_P(CODE) \
+ (TREE_CODE (CODE) == STRUCT_FIELD_TAG \
+ || TREE_CODE (CODE) == NAME_MEMORY_TAG \
+ || TREE_CODE (CODE) == TYPE_MEMORY_TAG)
+
+
/* Nonzero if DECL represents a VAR_DECL or FUNCTION_DECL. */
#define VAR_OR_FUNCTION_DECL_P(DECL)\
#define TYPE_CHECK(T) TREE_CLASS_CHECK (T, tcc_type)
#define DECL_MINIMAL_CHECK(T) CONTAINS_STRUCT_CHECK (T, TS_DECL_MINIMAL)
+#define TREE_MEMORY_TAG_CHECK(T) CONTAINS_STRUCT_CHECK (T, TS_MEMORY_TAG)
#define DECL_COMMON_CHECK(T) CONTAINS_STRUCT_CHECK (T, TS_DECL_COMMON)
#define DECL_WRTL_CHECK(T) CONTAINS_STRUCT_CHECK (T, TS_DECL_WRTL)
#define DECL_WITH_VIS_CHECK(T) CONTAINS_STRUCT_CHECK (T, TS_DECL_WITH_VIS)
/* Define fields and accessors for nodes representing declared names. */
/* Nonzero if DECL represents a variable for the SSA passes. */
-#define SSA_VAR_P(DECL) \
- (TREE_CODE (DECL) == VAR_DECL \
- || TREE_CODE (DECL) == PARM_DECL \
- || TREE_CODE (DECL) == RESULT_DECL \
- || (TREE_CODE (DECL) == SSA_NAME \
- && (TREE_CODE (SSA_NAME_VAR (DECL)) == VAR_DECL \
- || TREE_CODE (SSA_NAME_VAR (DECL)) == PARM_DECL \
- || TREE_CODE (SSA_NAME_VAR (DECL)) == RESULT_DECL)))
+#define SSA_VAR_P(DECL) \
+ (TREE_CODE (DECL) == VAR_DECL \
+ || TREE_CODE (DECL) == PARM_DECL \
+ || TREE_CODE (DECL) == RESULT_DECL \
+ || MTAG_P (DECL) \
+ || (TREE_CODE (DECL) == SSA_NAME \
+ && (TREE_CODE (SSA_NAME_VAR (DECL)) == VAR_DECL \
+ || TREE_CODE (SSA_NAME_VAR (DECL)) == PARM_DECL \
+ || TREE_CODE (SSA_NAME_VAR (DECL)) == RESULT_DECL \
+ || MTAG_P (SSA_NAME_VAR (DECL)))))
tree context;
};
+/* When computing aliasing information, we represent the memory pointed-to
+ by pointers with artificial variables called "memory tags" (MT). There
+ are two kinds of tags: type and name. Type tags (TMT) are used in
+ type-based alias analysis, they represent all the pointed-to locations
+ and variables of the same alias set class. Name tags (NMT) are used in
+ flow-sensitive points-to alias analysis, they represent the variables
+ and memory locations pointed-to by a specific SSA_NAME pointer. */
+
+struct tree_memory_tag GTY(())
+{
+ struct tree_decl_minimal common;
+ tree parent_var;
+ unsigned int is_global:1;
+};
+
+#define MTAG_GLOBAL(NODE) (TREE_MEMORY_TAG_CHECK (NODE)->mtag.is_global)
+#define SFT_PARENT_VAR(NODE) (STRUCT_FIELD_TAG_CHECK (NODE)->mtag.parent_var)
+
/* For any sort of a ..._DECL node, this points to the original (abstract)
decl node which this decl is an instance of, or else it is NULL indicating
that this decl is not an instance of some other decl. For example,
#define DECL_LANG_SPECIFIC(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.lang_specific)
/* In a VAR_DECL or FUNCTION_DECL, nonzero means external reference:
- do not allocate storage, and refer to a definition elsewhere. */
+ do not allocate storage, and refer to a definition elsewhere. Note that
+ this does not necessarily imply the entity represented by NODE
+ has no program source-level definition in this translation unit. For
+ example, for a FUNCTION_DECL, DECL_SAVED_TREE may be non-NULL and
+ DECL_EXTERNAL may be true simultaneously; that can be the case for
+ a C99 "extern inline" function. */
#define DECL_EXTERNAL(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.decl_flag_2)
/* In a VAR_DECL for a RECORD_TYPE, sets number for non-init_priority
struct tree_statement_list GTY ((tag ("TS_STATEMENT_LIST"))) stmt_list;
struct tree_value_handle GTY ((tag ("TS_VALUE_HANDLE"))) value_handle;
struct tree_constructor GTY ((tag ("TS_CONSTRUCTOR"))) constructor;
+ struct tree_memory_tag GTY ((tag ("TS_MEMORY_TAG"))) mtag;
};
\f
/* Standard named or nameless data types of the C compiler. */
/* Construct various types of nodes. */
-extern tree build (enum tree_code, tree, ...);
extern tree build_nt (enum tree_code, ...);
-#if GCC_VERSION >= 3000 || __STDC_VERSION__ >= 199901L
-/* Use preprocessor trickery to map "build" to "buildN" where N is the
- expected number of arguments. This is used for both efficiency (no
- varargs), and checking (verifying number of passed arguments). */
-#define build(code, ...) \
- _buildN1(build, _buildC1(__VA_ARGS__))(code, __VA_ARGS__)
-#define _buildN1(BASE, X) _buildN2(BASE, X)
-#define _buildN2(BASE, X) BASE##X
-#define _buildC1(...) _buildC2(__VA_ARGS__,9,8,7,6,5,4,3,2,1,0,0)
-#define _buildC2(x,a1,a2,a3,a4,a5,a6,a7,a8,a9,c,...) c
-#endif
-
extern tree build0_stat (enum tree_code, tree MEM_STAT_DECL);
#define build0(c,t) build0_stat (c,t MEM_STAT_INFO)
extern tree build1_stat (enum tree_code, tree, tree MEM_STAT_DECL);