Use identifier API for PyObject_GetAttrString.
diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py
index c66082e..5501ebc 100755
--- a/Parser/asdl_c.py
+++ b/Parser/asdl_c.py
@@ -85,8 +85,16 @@
 
     def __init__(self, file):
         self.file = file
+        self.identifiers = set()
         super(EmitVisitor, self).__init__()
 
+    def emit_identifier(self, name):
+        name = str(name)
+        if name in self.identifiers:
+            return
+        self.emit("_Py_identifier(%s);" % name, 0)
+        self.identifiers.add(name)
+
     def emit(self, s, depth, reflow=True):
         # XXX reflow long lines?
         if reflow:
@@ -486,12 +494,12 @@
 
     def visitField(self, field, name, sum=None, prod=None, depth=0):
         ctype = get_c_type(field.type)
-        self.emit("if (PyObject_HasAttrString(obj, \"%s\")) {" % field.name, depth)
+        self.emit("if (_PyObject_HasAttrId(obj, &PyId_%s)) {" % field.name, depth)
         self.emit("int res;", depth+1)
         if field.seq:
             self.emit("Py_ssize_t len;", depth+1)
             self.emit("Py_ssize_t i;", depth+1)
-        self.emit("tmp = PyObject_GetAttrString(obj, \"%s\");" % field.name, depth+1)
+        self.emit("tmp = _PyObject_GetAttrId(obj, &PyId_%s);" % field.name, depth+1)
         self.emit("if (tmp == NULL) goto failed;", depth+1)
         if field.seq:
             self.emit("if (!PyList_Check(tmp)) {", depth+1)
@@ -553,6 +561,8 @@
         self.emit("static PyTypeObject *%s_type;" % name, 0)
         self.emit("static PyObject* ast2obj_%s(void*);" % name, 0)
         if prod.fields:
+            for f in prod.fields:
+                self.emit_identifier(f.name)
             self.emit("static char *%s_fields[]={" % name,0)
             for f in prod.fields:
                 self.emit('"%s",' % f.name, 1)
@@ -561,6 +571,8 @@
     def visitSum(self, sum, name):
         self.emit("static PyTypeObject *%s_type;" % name, 0)
         if sum.attributes:
+            for a in sum.attributes:
+                self.emit_identifier(a.name)
             self.emit("static char *%s_attributes[] = {" % name, 0)
             for a in sum.attributes:
                 self.emit('"%s",' % a.name, 1)
@@ -580,6 +592,8 @@
     def visitConstructor(self, cons, name):
         self.emit("static PyTypeObject *%s_type;" % cons.name, 0)
         if cons.fields:
+            for t in cons.fields:
+                self.emit_identifier(t.name)
             self.emit("static char *%s_fields[]={" % cons.name, 0)
             for t in cons.fields:
                 self.emit('"%s",' % t.name, 1)
@@ -592,10 +606,11 @@
 static int
 ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
 {
+    _Py_identifier(_fields);
     Py_ssize_t i, numfields = 0;
     int res = -1;
     PyObject *key, *value, *fields;
-    fields = PyObject_GetAttrString((PyObject*)Py_TYPE(self), "_fields");
+    fields = _PyObject_GetAttrId((PyObject*)Py_TYPE(self), &PyId__fields);
     if (!fields)
         PyErr_Clear();
     if (fields) {
@@ -645,7 +660,8 @@
 ast_type_reduce(PyObject *self, PyObject *unused)
 {
     PyObject *res;
-    PyObject *dict = PyObject_GetAttrString(self, "__dict__");
+    _Py_identifier(__dict__);
+    PyObject *dict = _PyObject_GetAttrId(self, &PyId___dict__);
     if (dict == NULL) {
         if (PyErr_ExceptionMatches(PyExc_AttributeError))
             PyErr_Clear();