Ver Fonte

generalize AsVar by supporting `@:analyzer(as_var)` on types

closes #5850
closes #5808
Simon Krajewski há 8 anos atrás
pai
commit
60924d33c5

+ 1 - 0
extra/CHANGES.txt

@@ -5,6 +5,7 @@
 	all : fixed top-down inference infinite recursion issue (#5848)
 	all : fixed regression in Compiler.include (#5847)
 	all : fixed Not_found exception related to try/catch (#5851)
+	cpp : fixed issue with cpp.Pointer variables being eliminated (#5850)
 
 2016-11-29: 3.4.0-RC1
 

+ 1 - 0
src/optimization/analyzerConfig.ml

@@ -118,6 +118,7 @@ let update_config_from_meta com config meta =
 				| EConst (Ident s) when s = flag_user_var_fusion -> {config with user_var_fusion = true}
 				| EConst (Ident s) when s = "no_" ^ flag_user_var_fusion -> {config with user_var_fusion = false}
 				| EConst (Ident s) when s = flag_fusion_debug -> {config with fusion_debug = true}
+				| EConst (Ident s) when s = "as_var" -> config
 				| _ ->
 					let s = Ast.s_expr e in
 					com.warning (StringError.string_error s all_flags ("Unrecognized analyzer option: " ^ s)) (pos e);

+ 16 - 3
src/optimization/analyzerTexpr.ml

@@ -155,9 +155,22 @@ let is_ref_type = function
 	| TAbstract({a_path=["hl";"types"],"Ref"},_) -> true
 	| _ -> false
 
-let is_asvar_type t = match follow t with
-	| TAbstract({a_path = (["haxe";"extern"],"AsVar")},_) -> true
-	| _ -> false
+let rec is_asvar_type t =
+	let check meta =
+		AnalyzerConfig.has_analyzer_option meta "as_var"
+	in
+	match t with
+	| TInst(c,_) -> check c.cl_meta
+	| TEnum(en,_) -> check en.e_meta
+	| TType(t,tl) -> check t.t_meta || (is_asvar_type (apply_params t.t_params tl t.t_type))
+	| TAbstract(a,_) -> check a.a_meta
+	| TLazy f -> is_asvar_type (!f())
+	| TMono r ->
+		(match !r with
+		| Some t -> is_asvar_type t
+		| _ -> false)
+	| _ ->
+		false
 
 let type_change_ok com t1 t2 =
 	if t1 == t2 then

+ 2 - 1
std/cpp/Pointer.hx

@@ -24,6 +24,7 @@
 import haxe.extern.AsVar;
 
 @:coreType
+@:analyzer(as_var)
 extern class Pointer<T> extends ConstPointer<T> implements ArrayAccess<T>
 {
    public var ref(get,set):Reference<T>;
@@ -71,7 +72,7 @@ extern class Pointer<T> extends ConstPointer<T> implements ArrayAccess<T>
 
    inline public function toUnmanagedVector(elementCount:Int) : haxe.ds.Vector<T>
       return cast toUnmanagedArray(elementCount);
- 
+
 
    override public function inc():Pointer<T>;
    override public function dec():Pointer<T>;

+ 1 - 0
std/haxe/extern/AsVar.hx

@@ -27,4 +27,5 @@ package haxe.extern;
 	argument expressions are bound to a local variable.
 **/
 @:forward
+@:analyzer(as_var)
 abstract AsVar<T>(T) from T to T {}