]> granicus.if.org Git - php/commitdiff
Fixed Bug #55214 use of __CLASS__ within trait returns trait name not class name...
authorStefan Marr <gron@php.net>
Sun, 31 Jul 2011 18:18:56 +0000 (18:18 +0000)
committerStefan Marr <gron@php.net>
Sun, 31 Jul 2011 18:18:56 +0000 (18:18 +0000)
Zend/tests/traits/bug55214.phpt [new file with mode: 0644]
Zend/zend_compile.c
Zend/zend_language_scanner.c
Zend/zend_language_scanner.l
Zend/zend_language_scanner_defs.h

diff --git a/Zend/tests/traits/bug55214.phpt b/Zend/tests/traits/bug55214.phpt
new file mode 100644 (file)
index 0000000..9f3cb4f
--- /dev/null
@@ -0,0 +1,48 @@
+--TEST--
+Bug #55214 (Use of __CLASS__ within trait returns trait name not class name)
+--FILE--
+<?php
+
+trait ATrait {
+  public static function get_class_name() {
+    return __CLASS__;
+  }
+  
+  public function get_class_name_obj() {
+    return __CLASS__;
+  }
+}
+
+trait Indirect {
+       use ATrait;
+}
+
+class SomeClass {
+   use ATrait;
+}
+
+class UsingIndirect {
+       use Indirect;
+}
+
+$r = SomeClass::get_class_name();
+var_dump($r);
+
+$o = new SomeClass();
+$r = $o->get_class_name_obj();
+var_dump($r);
+
+$r = UsingIndirect::get_class_name();
+var_dump($r);
+
+$o = new UsingIndirect();
+$r = $o->get_class_name_obj();
+var_dump($r);
+
+
+?>
+--EXPECT--
+string(9) "SomeClass"
+string(9) "SomeClass"
+string(13) "UsingIndirect"
+string(13) "UsingIndirect"
index e8f9a04ff13b1adb6e08af1d623ef7cebb826acb..d8749f62bdfbdb3b1875406f2d51518ab27a4f5b 100644 (file)
@@ -3480,11 +3480,13 @@ static int zend_traits_merge_functions(zend_function *fn TSRMLS_DC, int num_args
 
 /* {{{ Originates from php_runkit_function_copy_ctor
        Duplicate structures in an op_array where necessary to make an outright duplicate */
-static void zend_traits_duplicate_function(zend_function *fe, char *newname TSRMLS_DC)
+static void zend_traits_duplicate_function(zend_function *fe, zend_class_entry *target_ce, char *newname TSRMLS_DC)
 {
        zend_literal *literals_copy;
        zend_compiled_variable *dupvars;
        zend_op *opcode_copy;
+       zval class_name_zv;
+       int class_name_literal;
        int i;
 
        if (fe->op_array.static_variables) {
@@ -3496,24 +3498,34 @@ static void zend_traits_duplicate_function(zend_function *fe, char *newname TSRM
 
                fe->op_array.static_variables = tmpHash;
        }
+  
+       /* TODO: Verify that this size is a global thing, do not see why but is used
+                like this elsewhere */
+       literals_copy = (zend_literal*)emalloc(CG(context).literals_size * sizeof(zend_literal));
+
+       for (i = 0; i < fe->op_array.last_literal; i++) {
+               literals_copy[i] = fe->op_array.literals[i];
+               zval_copy_ctor(&literals_copy[i].constant);
+       }
+       fe->op_array.literals = literals_copy;
+
 
        fe->op_array.refcount = emalloc(sizeof(zend_uint));
        *(fe->op_array.refcount) = 1;
 
-  if (fe->op_array.vars) {
-    i = fe->op_array.last_var;
-    dupvars = safe_emalloc(fe->op_array.last_var, sizeof(zend_compiled_variable), 0);
-    while (i > 0) {
-      i--;
-      dupvars[i].name = estrndup(fe->op_array.vars[i].name, fe->op_array.vars[i].name_len);
-      dupvars[i].name_len = fe->op_array.vars[i].name_len;
-      dupvars[i].hash_value = fe->op_array.vars[i].hash_value;
-    }
-    fe->op_array.vars = dupvars;
-  }
-       else {
-    fe->op_array.vars = NULL;
-  }
+       if (fe->op_array.vars) {
+               i = fe->op_array.last_var;
+               dupvars = safe_emalloc(fe->op_array.last_var, sizeof(zend_compiled_variable), 0);
+               while (i > 0) {
+                       i--;
+                       dupvars[i].name = estrndup(fe->op_array.vars[i].name, fe->op_array.vars[i].name_len);
+                       dupvars[i].name_len = fe->op_array.vars[i].name_len;
+                       dupvars[i].hash_value = fe->op_array.vars[i].hash_value;
+               }
+               fe->op_array.vars = dupvars;
+       } else {
+               fe->op_array.vars = NULL;
+       }
 
        opcode_copy = safe_emalloc(sizeof(zend_op), fe->op_array.last, 0);
        for(i = 0; i < fe->op_array.last; i++) {
@@ -3523,6 +3535,19 @@ static void zend_traits_duplicate_function(zend_function *fe, char *newname TSRM
                                opcode_copy[i].op1.jmp_addr <  fe->op_array.opcodes + fe->op_array.last) {
                                opcode_copy[i].op1.jmp_addr =  opcode_copy + (fe->op_array.opcodes[i].op1.jmp_addr - fe->op_array.opcodes);
                        }
+               } else {
+                       /* if __CLASS__ i.e. T_CLASS_C was used, we need to fix it up here */
+                       if (target_ce
+        /* REM: used a IS_NULL place holder with a special marker LVAL */
+                               && Z_TYPE_P(opcode_copy[i].op1.zv) == IS_NULL
+                               && Z_LVAL_P(opcode_copy[i].op1.zv) == ZEND_ACC_TRAIT
+        /* Only on merge into an actual class */
+        &&  (ZEND_ACC_TRAIT != (target_ce->ce_flags & ZEND_ACC_TRAIT))) {
+                               INIT_ZVAL(class_name_zv);
+                               ZVAL_STRINGL(&class_name_zv, target_ce->name, target_ce->name_length, 0);
+                               class_name_literal = zend_add_literal(&fe->op_array, &class_name_zv TSRMLS_CC);
+                               opcode_copy[i].op1.zv = &fe->op_array.literals[class_name_literal].constant;
+                       }
                }
 
                if (opcode_copy[i].op2_type != IS_CONST) {
@@ -3530,6 +3555,19 @@ static void zend_traits_duplicate_function(zend_function *fe, char *newname TSRM
                                opcode_copy[i].op2.jmp_addr <  fe->op_array.opcodes + fe->op_array.last) {
                                opcode_copy[i].op2.jmp_addr =  opcode_copy + (fe->op_array.opcodes[i].op2.jmp_addr - fe->op_array.opcodes);
                        }
+               } else {
+                       /* if __CLASS__ i.e. T_CLASS_C was used, we need to fix it up here */
+                       if (target_ce
+        /* REM: used a IS_NULL place holder with a special marker LVAL */
+                               && Z_TYPE_P(opcode_copy[i].op2.zv) == IS_NULL
+                               && Z_LVAL_P(opcode_copy[i].op2.zv) == ZEND_ACC_TRAIT
+        /* Only on merge into an actual class */
+        &&  (ZEND_ACC_TRAIT != (target_ce->ce_flags & ZEND_ACC_TRAIT))) {
+                               INIT_ZVAL(class_name_zv);
+                               ZVAL_STRINGL(&class_name_zv, target_ce->name, target_ce->name_length, 0);
+                               class_name_literal = zend_add_literal(&fe->op_array, &class_name_zv TSRMLS_CC);
+                               opcode_copy[i].op2.zv = &fe->op_array.literals[class_name_literal].constant;
+                       }
                }
        }
        fe->op_array.opcodes = opcode_copy;
@@ -3557,14 +3595,6 @@ static void zend_traits_duplicate_function(zend_function *fe, char *newname TSRM
 
        fe->op_array.brk_cont_array = (zend_brk_cont_element*)estrndup((char*)fe->op_array.brk_cont_array, sizeof(zend_brk_cont_element) * fe->op_array.last_brk_cont);
   
-       /* TODO: check whether there is something similar and whether that is ok */
-       literals_copy = (zend_literal*)emalloc(fe->op_array.last_literal * sizeof(zend_literal));
-  
-       for (i = 0; i < fe->op_array.last_literal; i++) {
-               literals_copy[i] = fe->op_array.literals[i];
-               zval_copy_ctor(&literals_copy[i].constant);
-       }
-       fe->op_array.literals = literals_copy;
 }
 /* }}}} */
 
@@ -3617,7 +3647,7 @@ static int zend_traits_merge_functions_to_class(zend_function *fn TSRMLS_DC, int
                        ce->ce_flags |= ZEND_HAS_STATIC_IN_METHODS;
                }
                fn_copy = *fn;
-               zend_traits_duplicate_function(&fn_copy, estrdup(fn->common.function_name) TSRMLS_CC);
+               zend_traits_duplicate_function(&fn_copy, ce, estrdup(fn->common.function_name) TSRMLS_CC);
 
                if (zend_hash_quick_update(&ce->function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, &fn_copy, sizeof(zend_function), (void**)&fn_copy_p)==FAILURE) {
                        zend_error(E_COMPILE_ERROR, "Trait method %s has not been applied, because failure occured during updating class method table", hash_key->arKey);
@@ -3639,6 +3669,7 @@ static int zend_traits_merge_functions_to_class(zend_function *fn TSRMLS_DC, int
 static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
 {
        HashTable* target;
+       zend_class_entry *target_ce;
        zend_trait_alias** aliases;
        HashTable* exclude_table;
        char* lcname;
@@ -3646,8 +3677,10 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args,
        zend_function fn_copy;
        void* dummy;
        size_t i = 0;
-       target = va_arg(args, HashTable*);
-       aliases = va_arg(args, zend_trait_alias**);
+       
+       target        = va_arg(args, HashTable*);
+       target_ce     = va_arg(args, zend_class_entry*);
+       aliases       = va_arg(args, zend_trait_alias**);
        exclude_table = va_arg(args, HashTable*);
   
        fnname_len = strlen(fn->common.function_name);
@@ -3661,7 +3694,7 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args,
                                && aliases[i]->trait_method->mname_len == fnname_len
                                && (zend_binary_strcasecmp(aliases[i]->trait_method->method_name, aliases[i]->trait_method->mname_len, fn->common.function_name, fnname_len) == 0)) {
                                fn_copy = *fn;
-                               zend_traits_duplicate_function(&fn_copy, estrndup(aliases[i]->alias, aliases[i]->alias_len) TSRMLS_CC);
+                               zend_traits_duplicate_function(&fn_copy, NULL, estrndup(aliases[i]->alias, aliases[i]->alias_len) TSRMLS_CC);
                                        
                                /* if it is 0, no modifieres has been changed */
                                if (aliases[i]->modifiers) { 
@@ -3688,7 +3721,7 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args,
        if (exclude_table == NULL || zend_hash_find(exclude_table, lcname, fnname_len, &dummy) == FAILURE) {
                /* is not in hashtable, thus, function is not to be excluded */
                fn_copy = *fn;
-               zend_traits_duplicate_function(&fn_copy, estrndup(fn->common.function_name, fnname_len) TSRMLS_CC);
+               zend_traits_duplicate_function(&fn_copy, NULL, estrndup(fn->common.function_name, fnname_len) TSRMLS_CC);
 
                /* apply aliases which are not qualified by a class name, or which have not
                 * alias name, just setting visibility */
@@ -3723,9 +3756,9 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args,
 /* }}} */
 
 /* Copies function table entries to target function table with applied aliasing */
-static void zend_traits_copy_trait_function_table(HashTable *target, HashTable *source, zend_trait_alias** aliases, HashTable* exclude_table TSRMLS_DC) /* {{{ */
+static void zend_traits_copy_trait_function_table(HashTable *target, zend_class_entry *target_ce, HashTable *source, zend_trait_alias** aliases, HashTable* exclude_table TSRMLS_DC) /* {{{ */
 {
-       zend_hash_apply_with_arguments(source TSRMLS_CC, (apply_func_args_t)zend_traits_copy_functions, 3, target, aliases, exclude_table);
+       zend_hash_apply_with_arguments(source TSRMLS_CC, (apply_func_args_t)zend_traits_copy_functions, 4, target, target_ce, aliases, exclude_table);
 }
 /* }}} */
 
@@ -3823,10 +3856,10 @@ static void zend_do_traits_method_binding(zend_class_entry *ce TSRMLS_DC) /* {{{
                        zend_traits_compile_exclude_table(&exclude_table, ce->trait_precedences, ce->traits[i]);
 
                        /* copies functions, applies defined aliasing, and excludes unused trait methods */
-                       zend_traits_copy_trait_function_table(function_tables[i], &ce->traits[i]->function_table, ce->trait_aliases, &exclude_table TSRMLS_CC);
+                       zend_traits_copy_trait_function_table(function_tables[i], ce, &ce->traits[i]->function_table, ce->trait_aliases, &exclude_table TSRMLS_CC);
                        zend_hash_graceful_destroy(&exclude_table);
                } else {
-                       zend_traits_copy_trait_function_table(function_tables[i], &ce->traits[i]->function_table, ce->trait_aliases, NULL TSRMLS_CC);
+                       zend_traits_copy_trait_function_table(function_tables[i], ce, &ce->traits[i]->function_table, ce->trait_aliases, NULL TSRMLS_CC);
                }
        }
   
index b512380c9b5de94155b8fa978be37411e37d6cca..afc75cd3bf1952e7e963443df1cf58608d5e1121 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Sun Jul 31 18:17:06 2011 */
+/* Generated by re2c 0.13.5 on Sun Jul 31 20:09:48 2011 */
 #line 1 "Zend/zend_language_scanner.l"
 /*
    +----------------------------------------------------------------------+
@@ -1083,7 +1083,7 @@ yyc_INITIAL:
 yy3:
                YYDEBUG(3, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1753 "Zend/zend_language_scanner.l"
+#line 1764 "Zend/zend_language_scanner.l"
                {
        if (YYCURSOR > YYLIMIT) {
                return 0;
@@ -1161,7 +1161,7 @@ yy5:
 yy6:
                YYDEBUG(6, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1741 "Zend/zend_language_scanner.l"
+#line 1752 "Zend/zend_language_scanner.l"
                {
        if (CG(short_tags)) {
                zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1180,7 +1180,7 @@ yy7:
                if ((yych = *YYCURSOR) == '=') goto yy43;
                YYDEBUG(8, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1718 "Zend/zend_language_scanner.l"
+#line 1729 "Zend/zend_language_scanner.l"
                {
        if (CG(asp_tags)) {
                zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1378,7 +1378,7 @@ yy35:
                ++YYCURSOR;
                YYDEBUG(38, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1678 "Zend/zend_language_scanner.l"
+#line 1689 "Zend/zend_language_scanner.l"
                {
        YYCTYPE *bracket = zend_memrchr(yytext, '<', yyleng - (sizeof("script language=php>") - 1));
 
@@ -1422,7 +1422,7 @@ yy43:
                ++YYCURSOR;
                YYDEBUG(44, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1696 "Zend/zend_language_scanner.l"
+#line 1707 "Zend/zend_language_scanner.l"
                {
        if (CG(asp_tags)) {
                zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1440,7 +1440,7 @@ yy45:
                ++YYCURSOR;
                YYDEBUG(46, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1709 "Zend/zend_language_scanner.l"
+#line 1720 "Zend/zend_language_scanner.l"
                {
        zendlval->value.str.val = yytext; /* no copying - intentional */
        zendlval->value.str.len = yyleng;
@@ -1475,7 +1475,7 @@ yy50:
 yy51:
                YYDEBUG(51, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1731 "Zend/zend_language_scanner.l"
+#line 1742 "Zend/zend_language_scanner.l"
                {
        zendlval->value.str.val = yytext; /* no copying - intentional */
        zendlval->value.str.len = yyleng;
@@ -1555,7 +1555,7 @@ yyc_ST_BACKQUOTE:
 yy56:
                YYDEBUG(56, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2204 "Zend/zend_language_scanner.l"
+#line 2215 "Zend/zend_language_scanner.l"
                {
        if (YYCURSOR > YYLIMIT) {
                return 0;
@@ -1607,7 +1607,7 @@ yy58:
                ++YYCURSOR;
                YYDEBUG(59, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2148 "Zend/zend_language_scanner.l"
+#line 2159 "Zend/zend_language_scanner.l"
                {
        BEGIN(ST_IN_SCRIPTING);
        return '`';
@@ -1622,7 +1622,7 @@ yy61:
                ++YYCURSOR;
                YYDEBUG(62, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2135 "Zend/zend_language_scanner.l"
+#line 2146 "Zend/zend_language_scanner.l"
                {
        zendlval->value.lval = (long) '{';
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
@@ -1645,7 +1645,7 @@ yy63:
 yy65:
                YYDEBUG(65, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1835 "Zend/zend_language_scanner.l"
+#line 1846 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
@@ -1676,7 +1676,7 @@ yy70:
                ++YYCURSOR;
                YYDEBUG(71, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1827 "Zend/zend_language_scanner.l"
+#line 1838 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 1);
        yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -1702,7 +1702,7 @@ yy73:
                ++YYCURSOR;
                YYDEBUG(74, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1817 "Zend/zend_language_scanner.l"
+#line 1828 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 3);
        yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -1778,7 +1778,7 @@ yy77:
 yy78:
                YYDEBUG(78, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2154 "Zend/zend_language_scanner.l"
+#line 2165 "Zend/zend_language_scanner.l"
                {
        if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) {
                YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1;
@@ -1838,7 +1838,7 @@ yy80:
                ++YYCURSOR;
                YYDEBUG(81, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2143 "Zend/zend_language_scanner.l"
+#line 2154 "Zend/zend_language_scanner.l"
                {
        BEGIN(ST_IN_SCRIPTING);
        return '"';
@@ -1853,7 +1853,7 @@ yy83:
                ++YYCURSOR;
                YYDEBUG(84, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2135 "Zend/zend_language_scanner.l"
+#line 2146 "Zend/zend_language_scanner.l"
                {
        zendlval->value.lval = (long) '{';
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
@@ -1876,7 +1876,7 @@ yy85:
 yy87:
                YYDEBUG(87, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1835 "Zend/zend_language_scanner.l"
+#line 1846 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
@@ -1907,7 +1907,7 @@ yy92:
                ++YYCURSOR;
                YYDEBUG(93, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1827 "Zend/zend_language_scanner.l"
+#line 1838 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 1);
        yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -1933,7 +1933,7 @@ yy95:
                ++YYCURSOR;
                YYDEBUG(96, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1817 "Zend/zend_language_scanner.l"
+#line 1828 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 3);
        yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -1952,7 +1952,7 @@ yyc_ST_END_HEREDOC:
        ++YYCURSOR;
        YYDEBUG(100, *YYCURSOR);
        yyleng = YYCURSOR - SCNG(yy_text);
-#line 2122 "Zend/zend_language_scanner.l"
+#line 2133 "Zend/zend_language_scanner.l"
        {
        YYCURSOR += CG(heredoc_len) - 1;
        yyleng = CG(heredoc_len);
@@ -2026,7 +2026,7 @@ yy103:
 yy104:
                YYDEBUG(104, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2246 "Zend/zend_language_scanner.l"
+#line 2257 "Zend/zend_language_scanner.l"
                {
        int newline = 0;
 
@@ -2112,7 +2112,7 @@ yy107:
                ++YYCURSOR;
                YYDEBUG(108, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2135 "Zend/zend_language_scanner.l"
+#line 2146 "Zend/zend_language_scanner.l"
                {
        zendlval->value.lval = (long) '{';
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
@@ -2135,7 +2135,7 @@ yy109:
 yy111:
                YYDEBUG(111, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1835 "Zend/zend_language_scanner.l"
+#line 1846 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
@@ -2166,7 +2166,7 @@ yy116:
                ++YYCURSOR;
                YYDEBUG(117, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1827 "Zend/zend_language_scanner.l"
+#line 1838 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 1);
        yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -2192,7 +2192,7 @@ yy119:
                ++YYCURSOR;
                YYDEBUG(120, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1817 "Zend/zend_language_scanner.l"
+#line 1828 "Zend/zend_language_scanner.l"
                {
        yyless(yyleng - 3);
        yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -2381,7 +2381,7 @@ yy123:
 yy124:
                YYDEBUG(124, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1858 "Zend/zend_language_scanner.l"
+#line 1869 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, yytext, yyleng);
        zendlval->type = IS_STRING;
@@ -2973,7 +2973,7 @@ yy175:
 yy176:
                YYDEBUG(176, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1865 "Zend/zend_language_scanner.l"
+#line 1876 "Zend/zend_language_scanner.l"
                {
        while (YYCURSOR < YYLIMIT) {
                switch (*YYCURSOR++) {
@@ -3014,7 +3014,7 @@ yy177:
 yy178:
                YYDEBUG(178, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1956 "Zend/zend_language_scanner.l"
+#line 1967 "Zend/zend_language_scanner.l"
                {
        register char *s, *t;
        char *end;
@@ -3089,7 +3089,7 @@ yy179:
 yy180:
                YYDEBUG(180, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2025 "Zend/zend_language_scanner.l"
+#line 2036 "Zend/zend_language_scanner.l"
                {
        int bprefix = (yytext[0] != '"') ? 1 : 0;
 
@@ -3136,7 +3136,7 @@ yy181:
                ++YYCURSOR;
                YYDEBUG(182, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2116 "Zend/zend_language_scanner.l"
+#line 2127 "Zend/zend_language_scanner.l"
                {
        BEGIN(ST_BACKQUOTE);
        return '`';
@@ -3147,7 +3147,7 @@ yy183:
                ++YYCURSOR;
                YYDEBUG(184, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2374 "Zend/zend_language_scanner.l"
+#line 2385 "Zend/zend_language_scanner.l"
                {
        if (YYCURSOR > YYLIMIT) {
                return 0;
@@ -3344,7 +3344,7 @@ yy205:
 yy206:
                YYDEBUG(206, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1933 "Zend/zend_language_scanner.l"
+#line 1944 "Zend/zend_language_scanner.l"
                {
        zendlval->value.str.val = yytext; /* no copying - intentional */
        zendlval->value.str.len = yyleng;
@@ -3386,7 +3386,7 @@ yy209:
 yy211:
                YYDEBUG(211, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1835 "Zend/zend_language_scanner.l"
+#line 1846 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
@@ -3482,7 +3482,7 @@ yy227:
 yy228:
                YYDEBUG(228, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1942 "Zend/zend_language_scanner.l"
+#line 1953 "Zend/zend_language_scanner.l"
                {
        if (CG(asp_tags)) {
                BEGIN(INITIAL);
@@ -3549,7 +3549,7 @@ yy237:
 yy238:
                YYDEBUG(238, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1899 "Zend/zend_language_scanner.l"
+#line 1910 "Zend/zend_language_scanner.l"
                {
        int doc_com;
 
@@ -3857,7 +3857,7 @@ yy278:
 yy279:
                YYDEBUG(279, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2067 "Zend/zend_language_scanner.l"
+#line 2078 "Zend/zend_language_scanner.l"
                {
        char *s;
        int bprefix = (yytext[0] != '<') ? 1 : 0;
@@ -4153,7 +4153,7 @@ yy316:
                }
                YYDEBUG(319, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1668 "Zend/zend_language_scanner.l"
+#line 1679 "Zend/zend_language_scanner.l"
                {
        if (CG(current_namespace)) {
                *zendlval = *CG(current_namespace);
@@ -4183,7 +4183,7 @@ yy321:
                }
                YYDEBUG(324, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1641 "Zend/zend_language_scanner.l"
+#line 1652 "Zend/zend_language_scanner.l"
                {
        char *filename = zend_get_compiled_filename(TSRMLS_C);
        const size_t filename_len = strlen(filename);
@@ -4235,7 +4235,7 @@ yy327:
                }
                YYDEBUG(330, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1623 "Zend/zend_language_scanner.l"
+#line 1634 "Zend/zend_language_scanner.l"
                {
        zendlval->value.lval = CG(zend_lineno);
        zendlval->type = IS_LONG;
@@ -4276,7 +4276,7 @@ yy335:
                }
                YYDEBUG(338, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1602 "Zend/zend_language_scanner.l"
+#line 1613 "Zend/zend_language_scanner.l"
                {
        char *class_name = CG(active_class_entry) ? CG(active_class_entry)->name : NULL;
        char *func_name = CG(active_op_array)? CG(active_op_array)->function_name : NULL;
@@ -4348,7 +4348,7 @@ yy346:
                }
                YYDEBUG(349, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1586 "Zend/zend_language_scanner.l"
+#line 1597 "Zend/zend_language_scanner.l"
                {
        char *func_name = NULL;
 
@@ -4384,7 +4384,7 @@ yy351:
                }
                YYDEBUG(354, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1629 "Zend/zend_language_scanner.l"
+#line 1640 "Zend/zend_language_scanner.l"
                {
        char *filename = zend_get_compiled_filename(TSRMLS_C);
 
@@ -4426,7 +4426,7 @@ yy358:
                }
                YYDEBUG(361, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1566 "Zend/zend_language_scanner.l"
+#line 1577 "Zend/zend_language_scanner.l"
                {
        char *trait_name = NULL;
        
@@ -4479,20 +4479,31 @@ yy365:
 #line 1550 "Zend/zend_language_scanner.l"
                {
        char *class_name = NULL;
-
-       if (CG(active_class_entry)) {
-               class_name = CG(active_class_entry)->name;
-       }
-
-       if (!class_name) {
-               class_name = "";
+       
+       if (CG(active_class_entry)
+               && (ZEND_ACC_TRAIT ==
+                       (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT))) {
+               // This is a hack, we abuse IS_NULL to indicate an invalid value
+               // if __CLASS__ is encountered in a trait, however, we also not that we
+               // should fix it up when we copy the method into an actual class
+               zendlval->value.lval = ZEND_ACC_TRAIT;
+               zendlval->type = IS_NULL;
+       } else {
+               if (CG(active_class_entry)) {
+                       class_name = CG(active_class_entry)->name;
+               }
+               
+               if (!class_name) {
+                       class_name = "";
+               }
+               
+               zendlval->value.str.len = strlen(class_name);
+               zendlval->value.str.val = estrndup(class_name, zendlval->value.str.len);
+               zendlval->type = IS_STRING;
        }
-       zendlval->value.str.len = strlen(class_name);
-       zendlval->value.str.val = estrndup(class_name, zendlval->value.str.len);
-       zendlval->type = IS_STRING;
        return T_CLASS_C;
 }
-#line 4496 "Zend/zend_language_scanner.c"
+#line 4507 "Zend/zend_language_scanner.c"
 yy369:
                YYDEBUG(369, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4558,7 +4569,7 @@ yy380:
                {
        return T_HALT_COMPILER;
 }
-#line 4562 "Zend/zend_language_scanner.c"
+#line 4573 "Zend/zend_language_scanner.c"
 yy382:
                YYDEBUG(382, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4582,7 +4593,7 @@ yy384:
                {
        return T_USE;
 }
-#line 4586 "Zend/zend_language_scanner.c"
+#line 4597 "Zend/zend_language_scanner.c"
 yy386:
                YYDEBUG(386, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4605,7 +4616,7 @@ yy388:
                {
        return T_UNSET;
 }
-#line 4609 "Zend/zend_language_scanner.c"
+#line 4620 "Zend/zend_language_scanner.c"
 yy390:
                YYDEBUG(390, *YYCURSOR);
                ++YYCURSOR;
@@ -4781,7 +4792,7 @@ yy405:
                {
        return T_INT_CAST;
 }
-#line 4785 "Zend/zend_language_scanner.c"
+#line 4796 "Zend/zend_language_scanner.c"
 yy408:
                YYDEBUG(408, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4829,7 +4840,7 @@ yy413:
                {
        return T_DOUBLE_CAST;
 }
-#line 4833 "Zend/zend_language_scanner.c"
+#line 4844 "Zend/zend_language_scanner.c"
 yy417:
                YYDEBUG(417, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4903,7 +4914,7 @@ yy427:
                {
        return T_STRING_CAST;
 }
-#line 4907 "Zend/zend_language_scanner.c"
+#line 4918 "Zend/zend_language_scanner.c"
 yy431:
                YYDEBUG(431, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4940,7 +4951,7 @@ yy434:
                {
        return T_ARRAY_CAST;
 }
-#line 4944 "Zend/zend_language_scanner.c"
+#line 4955 "Zend/zend_language_scanner.c"
 yy438:
                YYDEBUG(438, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -4982,7 +4993,7 @@ yy442:
                {
        return T_OBJECT_CAST;
 }
-#line 4986 "Zend/zend_language_scanner.c"
+#line 4997 "Zend/zend_language_scanner.c"
 yy446:
                YYDEBUG(446, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5027,7 +5038,7 @@ yy451:
                {
        return T_BOOL_CAST;
 }
-#line 5031 "Zend/zend_language_scanner.c"
+#line 5042 "Zend/zend_language_scanner.c"
 yy454:
                YYDEBUG(454, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5091,7 +5102,7 @@ yy462:
                {
        return T_UNSET_CAST;
 }
-#line 5095 "Zend/zend_language_scanner.c"
+#line 5106 "Zend/zend_language_scanner.c"
 yy466:
                YYDEBUG(466, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5109,7 +5120,7 @@ yy467:
                {
        return T_VAR;
 }
-#line 5113 "Zend/zend_language_scanner.c"
+#line 5124 "Zend/zend_language_scanner.c"
 yy469:
                YYDEBUG(469, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5133,7 +5144,7 @@ yy471:
                {
        return T_NEW;
 }
-#line 5137 "Zend/zend_language_scanner.c"
+#line 5148 "Zend/zend_language_scanner.c"
 yy473:
                YYDEBUG(473, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5176,7 +5187,7 @@ yy479:
                {
        return T_NAMESPACE;
 }
-#line 5180 "Zend/zend_language_scanner.c"
+#line 5191 "Zend/zend_language_scanner.c"
 yy481:
                YYDEBUG(481, *YYCURSOR);
                ++YYCURSOR;
@@ -5186,7 +5197,7 @@ yy481:
                {
        return T_PAAMAYIM_NEKUDOTAYIM;
 }
-#line 5190 "Zend/zend_language_scanner.c"
+#line 5201 "Zend/zend_language_scanner.c"
 yy483:
                YYDEBUG(483, *YYCURSOR);
                ++YYCURSOR;
@@ -5212,7 +5223,7 @@ yy485:
                {
        return T_MINUS_EQUAL;
 }
-#line 5216 "Zend/zend_language_scanner.c"
+#line 5227 "Zend/zend_language_scanner.c"
 yy487:
                YYDEBUG(487, *YYCURSOR);
                ++YYCURSOR;
@@ -5222,7 +5233,7 @@ yy487:
                {
        return T_DEC;
 }
-#line 5226 "Zend/zend_language_scanner.c"
+#line 5237 "Zend/zend_language_scanner.c"
 yy489:
                YYDEBUG(489, *YYCURSOR);
                ++YYCURSOR;
@@ -5233,7 +5244,7 @@ yy489:
        yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
        return T_OBJECT_OPERATOR;
 }
-#line 5237 "Zend/zend_language_scanner.c"
+#line 5248 "Zend/zend_language_scanner.c"
 yy491:
                YYDEBUG(491, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5282,7 +5293,7 @@ yy496:
                {
        return T_PUBLIC;
 }
-#line 5286 "Zend/zend_language_scanner.c"
+#line 5297 "Zend/zend_language_scanner.c"
 yy498:
                YYDEBUG(498, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5341,7 +5352,7 @@ yy505:
                {
        return T_PROTECTED;
 }
-#line 5345 "Zend/zend_language_scanner.c"
+#line 5356 "Zend/zend_language_scanner.c"
 yy507:
                YYDEBUG(507, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5375,7 +5386,7 @@ yy511:
                {
        return T_PRIVATE;
 }
-#line 5379 "Zend/zend_language_scanner.c"
+#line 5390 "Zend/zend_language_scanner.c"
 yy513:
                YYDEBUG(513, *YYCURSOR);
                ++YYCURSOR;
@@ -5388,7 +5399,7 @@ yy513:
                {
        return T_PRINT;
 }
-#line 5392 "Zend/zend_language_scanner.c"
+#line 5403 "Zend/zend_language_scanner.c"
 yy515:
                YYDEBUG(515, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5417,7 +5428,7 @@ yy518:
                {
        return T_GOTO;
 }
-#line 5421 "Zend/zend_language_scanner.c"
+#line 5432 "Zend/zend_language_scanner.c"
 yy520:
                YYDEBUG(520, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5445,7 +5456,7 @@ yy523:
                {
        return T_GLOBAL;
 }
-#line 5449 "Zend/zend_language_scanner.c"
+#line 5460 "Zend/zend_language_scanner.c"
 yy525:
                YYDEBUG(525, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5486,7 +5497,7 @@ yy531:
                {
        return T_BREAK;
 }
-#line 5490 "Zend/zend_language_scanner.c"
+#line 5501 "Zend/zend_language_scanner.c"
 yy533:
                YYDEBUG(533, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5530,7 +5541,7 @@ yy539:
                {
        return T_SWITCH;
 }
-#line 5534 "Zend/zend_language_scanner.c"
+#line 5545 "Zend/zend_language_scanner.c"
 yy541:
                YYDEBUG(541, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5558,7 +5569,7 @@ yy544:
                {
        return T_STATIC;
 }
-#line 5562 "Zend/zend_language_scanner.c"
+#line 5573 "Zend/zend_language_scanner.c"
 yy546:
                YYDEBUG(546, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5589,7 +5600,7 @@ yy549:
                {
        return T_AS;
 }
-#line 5593 "Zend/zend_language_scanner.c"
+#line 5604 "Zend/zend_language_scanner.c"
 yy551:
                YYDEBUG(551, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5612,7 +5623,7 @@ yy553:
                {
        return T_ARRAY;
 }
-#line 5616 "Zend/zend_language_scanner.c"
+#line 5627 "Zend/zend_language_scanner.c"
 yy555:
                YYDEBUG(555, *YYCURSOR);
                ++YYCURSOR;
@@ -5625,7 +5636,7 @@ yy555:
                {
        return T_LOGICAL_AND;
 }
-#line 5629 "Zend/zend_language_scanner.c"
+#line 5640 "Zend/zend_language_scanner.c"
 yy557:
                YYDEBUG(557, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5663,7 +5674,7 @@ yy562:
                {
        return T_ABSTRACT;
 }
-#line 5667 "Zend/zend_language_scanner.c"
+#line 5678 "Zend/zend_language_scanner.c"
 yy564:
                YYDEBUG(564, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5691,7 +5702,7 @@ yy567:
                {
        return T_WHILE;
 }
-#line 5695 "Zend/zend_language_scanner.c"
+#line 5706 "Zend/zend_language_scanner.c"
 yy569:
                YYDEBUG(569, *YYCURSOR);
                ++YYCURSOR;
@@ -5704,7 +5715,7 @@ yy569:
                {
        return T_IF;
 }
-#line 5708 "Zend/zend_language_scanner.c"
+#line 5719 "Zend/zend_language_scanner.c"
 yy571:
                YYDEBUG(571, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5760,7 +5771,7 @@ yy576:
                {
        return T_ISSET;
 }
-#line 5764 "Zend/zend_language_scanner.c"
+#line 5775 "Zend/zend_language_scanner.c"
 yy578:
                YYDEBUG(578, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5818,7 +5829,7 @@ yy585:
                {
        return T_INCLUDE;
 }
-#line 5822 "Zend/zend_language_scanner.c"
+#line 5833 "Zend/zend_language_scanner.c"
 yy586:
                YYDEBUG(586, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5851,7 +5862,7 @@ yy590:
                {
        return T_INCLUDE_ONCE;
 }
-#line 5855 "Zend/zend_language_scanner.c"
+#line 5866 "Zend/zend_language_scanner.c"
 yy592:
                YYDEBUG(592, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5889,7 +5900,7 @@ yy597:
                {
        return T_INTERFACE;
 }
-#line 5893 "Zend/zend_language_scanner.c"
+#line 5904 "Zend/zend_language_scanner.c"
 yy599:
                YYDEBUG(599, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5943,7 +5954,7 @@ yy605:
                {
         return T_INSTEADOF;
 }
-#line 5947 "Zend/zend_language_scanner.c"
+#line 5958 "Zend/zend_language_scanner.c"
 yy607:
                YYDEBUG(607, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -5976,7 +5987,7 @@ yy611:
                {
        return T_INSTANCEOF;
 }
-#line 5980 "Zend/zend_language_scanner.c"
+#line 5991 "Zend/zend_language_scanner.c"
 yy613:
                YYDEBUG(613, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6024,7 +6035,7 @@ yy620:
                {
        return T_IMPLEMENTS;
 }
-#line 6028 "Zend/zend_language_scanner.c"
+#line 6039 "Zend/zend_language_scanner.c"
 yy622:
                YYDEBUG(622, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6056,7 +6067,7 @@ yy623:
                {
        return T_TRY;
 }
-#line 6060 "Zend/zend_language_scanner.c"
+#line 6071 "Zend/zend_language_scanner.c"
 yy626:
                YYDEBUG(626, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6079,7 +6090,7 @@ yy628:
                {
        return T_TRAIT;
 }
-#line 6083 "Zend/zend_language_scanner.c"
+#line 6094 "Zend/zend_language_scanner.c"
 yy630:
                YYDEBUG(630, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6102,7 +6113,7 @@ yy632:
                {
        return T_THROW;
 }
-#line 6106 "Zend/zend_language_scanner.c"
+#line 6117 "Zend/zend_language_scanner.c"
 yy634:
                YYDEBUG(634, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6167,7 +6178,7 @@ yy641:
                {
        return T_REQUIRE;
 }
-#line 6171 "Zend/zend_language_scanner.c"
+#line 6182 "Zend/zend_language_scanner.c"
 yy642:
                YYDEBUG(642, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6200,7 +6211,7 @@ yy646:
                {
        return T_REQUIRE_ONCE;
 }
-#line 6204 "Zend/zend_language_scanner.c"
+#line 6215 "Zend/zend_language_scanner.c"
 yy648:
                YYDEBUG(648, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6223,7 +6234,7 @@ yy650:
                {
        return T_RETURN;
 }
-#line 6227 "Zend/zend_language_scanner.c"
+#line 6238 "Zend/zend_language_scanner.c"
 yy652:
                YYDEBUG(652, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6308,7 +6319,7 @@ yy661:
                {
        return T_CONTINUE;
 }
-#line 6312 "Zend/zend_language_scanner.c"
+#line 6323 "Zend/zend_language_scanner.c"
 yy663:
                YYDEBUG(663, *YYCURSOR);
                ++YYCURSOR;
@@ -6321,7 +6332,7 @@ yy663:
                {
        return T_CONST;
 }
-#line 6325 "Zend/zend_language_scanner.c"
+#line 6336 "Zend/zend_language_scanner.c"
 yy665:
                YYDEBUG(665, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6350,7 +6361,7 @@ yy668:
                {
        return T_CLONE;
 }
-#line 6354 "Zend/zend_language_scanner.c"
+#line 6365 "Zend/zend_language_scanner.c"
 yy670:
                YYDEBUG(670, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6368,7 +6379,7 @@ yy671:
                {
        return T_CLASS;
 }
-#line 6372 "Zend/zend_language_scanner.c"
+#line 6383 "Zend/zend_language_scanner.c"
 yy673:
                YYDEBUG(673, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6392,7 +6403,7 @@ yy675:
                {
        return T_CASE;
 }
-#line 6396 "Zend/zend_language_scanner.c"
+#line 6407 "Zend/zend_language_scanner.c"
 yy677:
                YYDEBUG(677, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6410,7 +6421,7 @@ yy678:
                {
        return T_CATCH;
 }
-#line 6414 "Zend/zend_language_scanner.c"
+#line 6425 "Zend/zend_language_scanner.c"
 yy680:
                YYDEBUG(680, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6465,7 +6476,7 @@ yy688:
                {
        return T_FUNCTION;
 }
-#line 6469 "Zend/zend_language_scanner.c"
+#line 6480 "Zend/zend_language_scanner.c"
 yy690:
                YYDEBUG(690, *YYCURSOR);
                ++YYCURSOR;
@@ -6493,7 +6504,7 @@ yy691:
                {
        return T_FOR;
 }
-#line 6497 "Zend/zend_language_scanner.c"
+#line 6508 "Zend/zend_language_scanner.c"
 yy692:
                YYDEBUG(692, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6521,7 +6532,7 @@ yy695:
                {
        return T_FOREACH;
 }
-#line 6525 "Zend/zend_language_scanner.c"
+#line 6536 "Zend/zend_language_scanner.c"
 yy697:
                YYDEBUG(697, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6544,7 +6555,7 @@ yy699:
                {
        return T_FINAL;
 }
-#line 6548 "Zend/zend_language_scanner.c"
+#line 6559 "Zend/zend_language_scanner.c"
 yy701:
                YYDEBUG(701, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6579,7 +6590,7 @@ yy703:
                {
        return T_DO;
 }
-#line 6583 "Zend/zend_language_scanner.c"
+#line 6594 "Zend/zend_language_scanner.c"
 yy705:
                YYDEBUG(705, *YYCURSOR);
                ++YYCURSOR;
@@ -6592,7 +6603,7 @@ yy705:
                {
        return T_EXIT;
 }
-#line 6596 "Zend/zend_language_scanner.c"
+#line 6607 "Zend/zend_language_scanner.c"
 yy707:
                YYDEBUG(707, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6631,7 +6642,7 @@ yy712:
                {
        return T_DEFAULT;
 }
-#line 6635 "Zend/zend_language_scanner.c"
+#line 6646 "Zend/zend_language_scanner.c"
 yy714:
                YYDEBUG(714, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6659,7 +6670,7 @@ yy717:
                {
        return T_DECLARE;
 }
-#line 6663 "Zend/zend_language_scanner.c"
+#line 6674 "Zend/zend_language_scanner.c"
 yy719:
                YYDEBUG(719, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6743,7 +6754,7 @@ yy730:
                {
        return T_EXTENDS;
 }
-#line 6747 "Zend/zend_language_scanner.c"
+#line 6758 "Zend/zend_language_scanner.c"
 yy732:
                YYDEBUG(732, *YYCURSOR);
                ++YYCURSOR;
@@ -6756,7 +6767,7 @@ yy732:
                {
        return T_EXIT;
 }
-#line 6760 "Zend/zend_language_scanner.c"
+#line 6771 "Zend/zend_language_scanner.c"
 yy734:
                YYDEBUG(734, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6774,7 +6785,7 @@ yy735:
                {
        return T_EVAL;
 }
-#line 6778 "Zend/zend_language_scanner.c"
+#line 6789 "Zend/zend_language_scanner.c"
 yy737:
                YYDEBUG(737, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6848,7 +6859,7 @@ yy746:
                {
        return T_ENDWHILE;
 }
-#line 6852 "Zend/zend_language_scanner.c"
+#line 6863 "Zend/zend_language_scanner.c"
 yy748:
                YYDEBUG(748, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6881,7 +6892,7 @@ yy752:
                {
        return T_ENDSWITCH;
 }
-#line 6885 "Zend/zend_language_scanner.c"
+#line 6896 "Zend/zend_language_scanner.c"
 yy754:
                YYDEBUG(754, *YYCURSOR);
                ++YYCURSOR;
@@ -6894,7 +6905,7 @@ yy754:
                {
        return T_ENDIF;
 }
-#line 6898 "Zend/zend_language_scanner.c"
+#line 6909 "Zend/zend_language_scanner.c"
 yy756:
                YYDEBUG(756, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6927,7 +6938,7 @@ yy758:
                {
        return T_ENDFOR;
 }
-#line 6931 "Zend/zend_language_scanner.c"
+#line 6942 "Zend/zend_language_scanner.c"
 yy759:
                YYDEBUG(759, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6955,7 +6966,7 @@ yy762:
                {
        return T_ENDFOREACH;
 }
-#line 6959 "Zend/zend_language_scanner.c"
+#line 6970 "Zend/zend_language_scanner.c"
 yy764:
                YYDEBUG(764, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -6993,7 +7004,7 @@ yy769:
                {
        return T_ENDDECLARE;
 }
-#line 6997 "Zend/zend_language_scanner.c"
+#line 7008 "Zend/zend_language_scanner.c"
 yy771:
                YYDEBUG(771, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7016,7 +7027,7 @@ yy773:
                {
        return T_EMPTY;
 }
-#line 7020 "Zend/zend_language_scanner.c"
+#line 7031 "Zend/zend_language_scanner.c"
 yy775:
                YYDEBUG(775, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7049,7 +7060,7 @@ yy777:
                {
        return T_ELSE;
 }
-#line 7053 "Zend/zend_language_scanner.c"
+#line 7064 "Zend/zend_language_scanner.c"
 yy778:
                YYDEBUG(778, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7067,7 +7078,7 @@ yy779:
                {
        return T_ELSEIF;
 }
-#line 7071 "Zend/zend_language_scanner.c"
+#line 7082 "Zend/zend_language_scanner.c"
 yy781:
                YYDEBUG(781, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7085,7 +7096,7 @@ yy782:
                {
        return T_ECHO;
 }
-#line 7089 "Zend/zend_language_scanner.c"
+#line 7100 "Zend/zend_language_scanner.c"
        }
 /* *********************************** */
 yyc_ST_LOOKING_FOR_PROPERTY:
@@ -7166,7 +7177,7 @@ yy787:
        HANDLE_NEWLINES(yytext, yyleng);
        return T_WHITESPACE;
 }
-#line 7170 "Zend/zend_language_scanner.c"
+#line 7181 "Zend/zend_language_scanner.c"
 yy788:
                YYDEBUG(788, *YYCURSOR);
                ++YYCURSOR;
@@ -7180,7 +7191,7 @@ yy789:
        yy_pop_state(TSRMLS_C);
        goto restart;
 }
-#line 7184 "Zend/zend_language_scanner.c"
+#line 7195 "Zend/zend_language_scanner.c"
 yy790:
                YYDEBUG(790, *YYCURSOR);
                ++YYCURSOR;
@@ -7196,7 +7207,7 @@ yy791:
        zendlval->type = IS_STRING;
        return T_STRING;
 }
-#line 7200 "Zend/zend_language_scanner.c"
+#line 7211 "Zend/zend_language_scanner.c"
 yy792:
                YYDEBUG(792, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7221,7 +7232,7 @@ yy795:
                {
        return T_OBJECT_OPERATOR;
 }
-#line 7225 "Zend/zend_language_scanner.c"
+#line 7236 "Zend/zend_language_scanner.c"
 yy797:
                YYDEBUG(797, *YYCURSOR);
                ++YYCURSOR;
@@ -7299,7 +7310,7 @@ yy802:
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
        return T_STRING_VARNAME;
 }
-#line 7303 "Zend/zend_language_scanner.c"
+#line 7314 "Zend/zend_language_scanner.c"
 yy803:
                YYDEBUG(803, *YYCURSOR);
                ++YYCURSOR;
@@ -7312,7 +7323,7 @@ yy803:
        yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
        goto restart;
 }
-#line 7316 "Zend/zend_language_scanner.c"
+#line 7327 "Zend/zend_language_scanner.c"
 yy805:
                YYDEBUG(805, *YYCURSOR);
                ++YYCURSOR;
@@ -7334,7 +7345,7 @@ yyc_ST_NOWDOC:
        ++YYCURSOR;
        YYDEBUG(810, *YYCURSOR);
        yyleng = YYCURSOR - SCNG(yy_text);
-#line 2318 "Zend/zend_language_scanner.l"
+#line 2329 "Zend/zend_language_scanner.l"
        {
        int newline = 0;
 
@@ -7389,7 +7400,7 @@ nowdoc_scan_done:
        HANDLE_NEWLINES(yytext, yyleng - newline);
        return T_ENCAPSED_AND_WHITESPACE;
 }
-#line 7393 "Zend/zend_language_scanner.c"
+#line 7404 "Zend/zend_language_scanner.c"
 /* *********************************** */
 yyc_ST_VAR_OFFSET:
        {
@@ -7508,7 +7519,7 @@ yy814:
        }
        return T_NUM_STRING;
 }
-#line 7512 "Zend/zend_language_scanner.c"
+#line 7523 "Zend/zend_language_scanner.c"
 yy815:
                YYDEBUG(815, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7528,23 +7539,23 @@ yy816:
 yy817:
                YYDEBUG(817, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1846 "Zend/zend_language_scanner.l"
+#line 1857 "Zend/zend_language_scanner.l"
                {
        /* Only '[' can be valid, but returning other tokens will allow a more explicit parse error */
        return yytext[0];
 }
-#line 7537 "Zend/zend_language_scanner.c"
+#line 7548 "Zend/zend_language_scanner.c"
 yy818:
                YYDEBUG(818, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(819, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1841 "Zend/zend_language_scanner.l"
+#line 1852 "Zend/zend_language_scanner.l"
                {
        yy_pop_state(TSRMLS_C);
        return ']';
 }
-#line 7548 "Zend/zend_language_scanner.c"
+#line 7559 "Zend/zend_language_scanner.c"
 yy820:
                YYDEBUG(820, *YYCURSOR);
                yych = *++YYCURSOR;
@@ -7554,14 +7565,14 @@ yy821:
                ++YYCURSOR;
                YYDEBUG(822, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1851 "Zend/zend_language_scanner.l"
+#line 1862 "Zend/zend_language_scanner.l"
                {
        /* Invalid rule to return a more explicit parse error with proper line number */
        yyless(0);
        yy_pop_state(TSRMLS_C);
        return T_ENCAPSED_AND_WHITESPACE;
 }
-#line 7565 "Zend/zend_language_scanner.c"
+#line 7576 "Zend/zend_language_scanner.c"
 yy823:
                YYDEBUG(823, *YYCURSOR);
                ++YYCURSOR;
@@ -7570,19 +7581,19 @@ yy823:
 yy824:
                YYDEBUG(824, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1858 "Zend/zend_language_scanner.l"
+#line 1869 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, yytext, yyleng);
        zendlval->type = IS_STRING;
        return T_STRING;
 }
-#line 7580 "Zend/zend_language_scanner.c"
+#line 7591 "Zend/zend_language_scanner.c"
 yy825:
                YYDEBUG(825, *YYCURSOR);
                ++YYCURSOR;
                YYDEBUG(826, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 2374 "Zend/zend_language_scanner.l"
+#line 2385 "Zend/zend_language_scanner.l"
                {
        if (YYCURSOR > YYLIMIT) {
                return 0;
@@ -7591,7 +7602,7 @@ yy825:
        zend_error(E_COMPILE_WARNING,"Unexpected character in input:  '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
        goto restart;
 }
-#line 7595 "Zend/zend_language_scanner.c"
+#line 7606 "Zend/zend_language_scanner.c"
 yy827:
                YYDEBUG(827, *YYCURSOR);
                ++YYCURSOR;
@@ -7627,13 +7638,13 @@ yy829:
 yy831:
                YYDEBUG(831, *YYCURSOR);
                yyleng = YYCURSOR - SCNG(yy_text);
-#line 1835 "Zend/zend_language_scanner.l"
+#line 1846 "Zend/zend_language_scanner.l"
                {
        zend_copy_value(zendlval, (yytext+1), (yyleng-1));
        zendlval->type = IS_STRING;
        return T_VARIABLE;
 }
-#line 7637 "Zend/zend_language_scanner.c"
+#line 7648 "Zend/zend_language_scanner.c"
 yy832:
                YYDEBUG(832, *YYCURSOR);
                ++YYCURSOR;
@@ -7680,7 +7691,7 @@ yy839:
        zendlval->type = IS_STRING;
        return T_NUM_STRING;
 }
-#line 7684 "Zend/zend_language_scanner.c"
+#line 7695 "Zend/zend_language_scanner.c"
 yy840:
                YYDEBUG(840, *YYCURSOR);
                ++YYCURSOR;
@@ -7703,6 +7714,6 @@ yy842:
                goto yy839;
        }
 }
-#line 2383 "Zend/zend_language_scanner.l"
+#line 2394 "Zend/zend_language_scanner.l"
 
 }
index 1a22f0b7e19c22a067cc0cddfb52829360dc2d5d..73e22e209e522ae7682d78adfa4818729a9b737d 100644 (file)
@@ -1549,17 +1549,28 @@ NEWLINE ("\r"|"\n"|"\r\n")
 
 <ST_IN_SCRIPTING>"__CLASS__" {
        char *class_name = NULL;
-
-       if (CG(active_class_entry)) {
-               class_name = CG(active_class_entry)->name;
-       }
-
-       if (!class_name) {
-               class_name = "";
+       
+       if (CG(active_class_entry)
+               && (ZEND_ACC_TRAIT ==
+                       (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT))) {
+               // This is a hack, we abuse IS_NULL to indicate an invalid value
+               // if __CLASS__ is encountered in a trait, however, we also not that we
+               // should fix it up when we copy the method into an actual class
+               zendlval->value.lval = ZEND_ACC_TRAIT;
+               zendlval->type = IS_NULL;
+       } else {
+               if (CG(active_class_entry)) {
+                       class_name = CG(active_class_entry)->name;
+               }
+               
+               if (!class_name) {
+                       class_name = "";
+               }
+               
+               zendlval->value.str.len = strlen(class_name);
+               zendlval->value.str.val = estrndup(class_name, zendlval->value.str.len);
+               zendlval->type = IS_STRING;
        }
-       zendlval->value.str.len = strlen(class_name);
-       zendlval->value.str.val = estrndup(class_name, zendlval->value.str.len);
-       zendlval->type = IS_STRING;
        return T_CLASS_C;
 }
 
index 34f98e3682046cbfe5df2e4313adfae81d3fc0a6..1fbeabfc9d9df993c4dca1f1af116720ad6c9b66 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Sun Jul 31 18:17:06 2011 */
+/* Generated by re2c 0.13.5 on Sun Jul 31 20:09:48 2011 */
 #line 3 "Zend/zend_language_scanner_defs.h"
 
 enum YYCONDTYPE {