本文整理汇总了C++中ParseNode::makeEmpty方法的典型用法代码示例。如果您正苦于以下问题:C++ ParseNode::makeEmpty方法的具体用法?C++ ParseNode::makeEmpty怎么用?C++ ParseNode::makeEmpty使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ParseNode
的用法示例。
在下文中一共展示了ParseNode::makeEmpty方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: source
//.........这里部分代码省略.........
JSAtom *atom = js_AtomizeString(cx, source);
jsatomid _;
if (!atom || !bce.makeAtomIndex(atom, &_))
return NULL;
}
if (callerFrame && callerFrame->isFunctionFrame()) {
/*
* An eval script in a caller frame needs to have its enclosing
* function captured in case it refers to an upvar, and someone
* wishes to decompile it while it's running.
*/
ObjectBox *funbox = parser.newObjectBox(callerFrame->fun());
if (!funbox)
return NULL;
funbox->emitLink = bce.objectList.lastbox;
bce.objectList.lastbox = funbox;
bce.objectList.length++;
}
}
ParseNode *pn;
#if JS_HAS_XML_SUPPORT
pn = NULL;
bool onlyXML;
onlyXML = true;
#endif
TokenStream &tokenStream = parser.tokenStream;
{
ParseNode *stringsAtStart = ListNode::create(PNK_STATEMENTLIST, &parser);
if (!stringsAtStart)
return NULL;
stringsAtStart->makeEmpty();
bool ok = parser.processDirectives(stringsAtStart) && EmitTree(cx, &bce, stringsAtStart);
parser.freeTree(stringsAtStart);
if (!ok)
return NULL;
}
JS_ASSERT(sc.strictModeState != StrictMode::UNKNOWN);
for (;;) {
TokenKind tt = tokenStream.peekToken(TSF_OPERAND);
if (tt <= TOK_EOF) {
if (tt == TOK_EOF)
break;
JS_ASSERT(tt == TOK_ERROR);
return NULL;
}
pn = parser.statement();
if (!pn)
return NULL;
if (!FoldConstants(cx, pn, &parser))
return NULL;
if (!AnalyzeFunctions(&parser, callerFrame))
return NULL;
tc.functionList = NULL;
if (!EmitTree(cx, &bce, pn))
return NULL;
#if JS_HAS_XML_SUPPORT
if (!pn->isKind(PNK_SEMI) || !pn->pn_kid || !pn->pn_kid->isXMLItem())
onlyXML = false;
示例2: skip
// Compile a JS function body, which might appear as the value of an event
// handler attribute in an HTML <INPUT> tag, or in a Function() constructor.
bool
frontend::CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileOptions options,
const AutoNameVector &formals, const jschar *chars, size_t length,
bool isAsmJSRecompile)
{
SkipRoot skip(cx, &chars);
if (!CheckLength(cx, length))
return false;
ScriptSource *ss = cx->new_<ScriptSource>();
if (!ss)
return false;
if (options.filename && !ss->setFilename(cx, options.filename))
return false;
JS::RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, ss));
if (!sourceObject)
return false;
SourceCompressionToken sct(cx);
JS_ASSERT(options.sourcePolicy != CompileOptions::LAZY_SOURCE);
if (options.sourcePolicy == CompileOptions::SAVE_SOURCE) {
if (!ss->setSourceCopy(cx, chars, length, true, &sct))
return false;
}
bool canLazilyParse = CanLazilyParse(cx, options);
Maybe<Parser<SyntaxParseHandler> > syntaxParser;
if (canLazilyParse) {
syntaxParser.construct(cx, options, chars, length, /* foldConstants = */ false,
(Parser<SyntaxParseHandler> *) NULL,
(LazyScript *) NULL);
}
JS_ASSERT(!options.forEval);
Parser<FullParseHandler> parser(cx, options, chars, length, /* foldConstants = */ true,
canLazilyParse ? &syntaxParser.ref() : NULL, NULL);
parser.sct = &sct;
JS_ASSERT(fun);
JS_ASSERT(fun->isTenured());
fun->setArgCount(formals.length());
/* FIXME: make Function format the source for a function definition. */
ParseNode *fn = CodeNode::create(PNK_FUNCTION, &parser.handler);
if (!fn)
return false;
fn->pn_body = NULL;
fn->pn_funbox = NULL;
fn->pn_cookie.makeFree();
ParseNode *argsbody = ListNode::create(PNK_ARGSBODY, &parser.handler);
if (!argsbody)
return false;
argsbody->setOp(JSOP_NOP);
argsbody->makeEmpty();
fn->pn_body = argsbody;
Rooted<JSScript*> script(cx, JSScript::Create(cx, NullPtr(), false, options,
/* staticLevel = */ 0, sourceObject,
/* sourceStart = */ 0, length));
if (!script)
return false;
// If the context is strict, immediately parse the body in strict
// mode. Otherwise, we parse it normally. If we see a "use strict"
// directive, we backup and reparse it as strict.
TokenStream::Position start(parser.keepAtoms);
parser.tokenStream.tell(&start);
bool strict = StrictModeFromContext(cx);
bool becameStrict;
FunctionBox *funbox;
ParseNode *pn;
while (true) {
pn = parser.standaloneFunctionBody(fun, formals, script, fn, &funbox,
strict, &becameStrict);
if (pn)
break;
if (parser.hadAbortedSyntaxParse()) {
// Hit some unrecoverable ambiguity during an inner syntax parse.
// Syntax parsing has now been disabled in the parser, so retry
// the parse.
parser.clearAbortedSyntaxParse();
} else {
// If the function became strict, reparse in strict mode.
if (strict || !becameStrict || parser.tokenStream.hadError())
return false;
strict = true;
}
parser.tokenStream.seek(start);
}
if (!NameFunctions(cx, pn))
return false;
//.........这里部分代码省略.........
示例3: attacher
// Compile a JS function body, which might appear as the value of an event
// handler attribute in an HTML <INPUT> tag, or in a Function() constructor.
bool
frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions options,
Bindings *bindings, const jschar *chars, size_t length)
{
if (!CheckLength(cx, length))
return NULL;
ScriptSource *ss = cx->new_<ScriptSource>();
if (!ss)
return NULL;
AutoAttachToRuntime attacher(cx->runtime, ss);
SourceCompressionToken sct(cx);
if (!ss->setSourceCopy(cx, chars, length, true, &sct))
return NULL;
options.setCompileAndGo(false);
Parser parser(cx, options, chars, length, /* foldConstants = */ true);
if (!parser.init())
return false;
parser.sct = &sct;
JS_ASSERT(fun);
SharedContext funsc(cx, /* scopeChain = */ NULL, fun, /* funbox = */ NULL,
StrictModeFromContext(cx));
funsc.bindings.transfer(bindings);
fun->setArgCount(funsc.bindings.numArgs());
unsigned staticLevel = 0;
TreeContext funtc(&parser, &funsc, staticLevel, /* bodyid = */ 0);
if (!funtc.init())
return false;
Rooted<JSScript*> script(cx, JSScript::Create(cx, NullPtr(), false, options,
staticLevel, ss, 0, length));
if (!script)
return false;
StackFrame *nullCallerFrame = NULL;
BytecodeEmitter funbce(/* parent = */ NULL, &parser, &funsc, script, nullCallerFrame,
/* hasGlobalScope = */ false, options.lineno);
if (!funbce.init())
return false;
/* FIXME: make Function format the source for a function definition. */
ParseNode *fn = FunctionNode::create(PNK_NAME, &parser);
if (!fn)
return false;
fn->pn_body = NULL;
fn->pn_cookie.makeFree();
ParseNode *argsbody = ListNode::create(PNK_ARGSBODY, &parser);
if (!argsbody)
return false;
argsbody->setOp(JSOP_NOP);
argsbody->makeEmpty();
fn->pn_body = argsbody;
unsigned nargs = fun->nargs;
if (nargs) {
/*
* NB: do not use AutoLocalNameArray because it will release space
* allocated from cx->tempLifoAlloc by DefineArg.
*/
BindingVector names(cx);
if (!GetOrderedBindings(cx, funsc.bindings, &names))
return false;
for (unsigned i = 0; i < nargs; i++) {
if (!DefineArg(fn, names[i].maybeName, i, &parser))
return false;
}
}
/*
* After we're done parsing, we must fold constants, analyze any nested
* functions, and generate code for this function, including a stop opcode
* at the end.
*/
ParseNode *pn = parser.functionBody(Parser::StatementListBody);
if (!pn)
return false;
if (!parser.tokenStream.matchToken(TOK_EOF)) {
parser.reportError(NULL, JSMSG_SYNTAX_ERROR);
return false;
}
if (!FoldConstants(cx, pn, &parser))
return false;
if (!AnalyzeFunctions(&parser, nullCallerFrame))
return false;
if (fn->pn_body) {
JS_ASSERT(fn->pn_body->isKind(PNK_ARGSBODY));
fn->pn_body->append(pn);
fn->pn_body->pn_pos = pn->pn_pos;
pn = fn->pn_body;
//.........这里部分代码省略.........
示例4: ssh
// Compile a JS function body, which might appear as the value of an event
// handler attribute in an HTML <INPUT> tag, or in a Function() constructor.
bool
frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions options,
const AutoNameVector &formals, StableCharPtr chars, size_t length)
{
if (!CheckLength(cx, length))
return false;
ScriptSource *ss = cx->new_<ScriptSource>();
if (!ss)
return false;
ScriptSourceHolder ssh(ss);
SourceCompressionToken sct(cx);
JS_ASSERT(options.sourcePolicy != CompileOptions::LAZY_SOURCE);
if (options.sourcePolicy == CompileOptions::SAVE_SOURCE) {
if (!ss->setSourceCopy(cx, chars, length, true, &sct))
return false;
}
options.setCompileAndGo(false);
Parser parser(cx, options, chars, length, /* foldConstants = */ true);
if (!parser.init())
return false;
parser.sct = &sct;
JS_ASSERT(fun);
fun->setArgCount(formals.length());
/* FIXME: make Function format the source for a function definition. */
ParseNode *fn = FunctionNode::create(PNK_FUNCTION, &parser);
if (!fn)
return false;
fn->pn_body = NULL;
fn->pn_funbox = NULL;
fn->pn_cookie.makeFree();
ParseNode *argsbody = ListNode::create(PNK_ARGSBODY, &parser);
if (!argsbody)
return false;
argsbody->setOp(JSOP_NOP);
argsbody->makeEmpty();
fn->pn_body = argsbody;
Rooted<JSScript*> script(cx, JSScript::Create(cx, NullPtr(), false, options,
/* staticLevel = */ 0, ss,
/* sourceStart = */ 0, length));
if (!script)
return false;
// If the context is strict, immediately parse the body in strict
// mode. Otherwise, we parse it normally. If we see a "use strict"
// directive, we backup and reparse it as strict.
TokenStream::Position start;
parser.tokenStream.tell(&start);
bool initiallyStrict = StrictModeFromContext(cx);
bool becameStrict;
FunctionBox *funbox;
ParseNode *pn = parser.standaloneFunctionBody(fun, formals, script, fn, &funbox,
initiallyStrict, &becameStrict);
if (!pn) {
if (initiallyStrict || !becameStrict || parser.tokenStream.hadError())
return false;
// Reparse in strict mode.
parser.tokenStream.seek(start);
pn = parser.standaloneFunctionBody(fun, formals, script, fn, &funbox,
/* strict = */ true);
if (!pn)
return false;
}
BytecodeEmitter funbce(/* parent = */ NULL, &parser, funbox, script,
/* callerFrame = */ NullFramePtr(),
/* hasGlobalScope = */ false, options.lineno);
if (!funbce.init())
return false;
if (!NameFunctions(cx, pn))
return false;
if (fn->pn_body) {
JS_ASSERT(fn->pn_body->isKind(PNK_ARGSBODY));
fn->pn_body->append(pn);
fn->pn_body->pn_pos = pn->pn_pos;
pn = fn->pn_body;
}
if (!SetSourceMap(cx, parser.tokenStream, ss, script))
return false;
if (!EmitFunctionScript(cx, &funbce, pn))
return false;
if (!sct.complete())
return false;
return true;
}
示例5: ssh
// Compile a JS function body, which might appear as the value of an event
// handler attribute in an HTML <INPUT> tag, or in a Function() constructor.
bool
frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions options,
const AutoNameVector &formals, const jschar *chars, size_t length)
{
if (!CheckLength(cx, length))
return false;
ScriptSource *ss = cx->new_<ScriptSource>();
if (!ss)
return false;
ScriptSourceHolder ssh(cx->runtime, ss);
SourceCompressionToken sct(cx);
JS_ASSERT(options.sourcePolicy != CompileOptions::LAZY_SOURCE);
if (options.sourcePolicy == CompileOptions::SAVE_SOURCE) {
if (!ss->setSourceCopy(cx, chars, length, true, &sct))
return false;
}
options.setCompileAndGo(false);
Parser parser(cx, options, chars, length, /* foldConstants = */ true);
if (!parser.init())
return false;
parser.sct = &sct;
JS_ASSERT(fun);
StrictMode sms = StrictModeFromContext(cx);
FunctionBox *funbox = parser.newFunctionBox(fun, /* outerpc = */ NULL, sms);
SharedContext funsc(cx, /* scopeChain = */ NULL, funbox, sms);
fun->setArgCount(formals.length());
unsigned staticLevel = 0;
ParseContext funpc(&parser, &funsc, staticLevel, /* bodyid = */ 0);
if (!funpc.init())
return false;
/* FIXME: make Function format the source for a function definition. */
ParseNode *fn = FunctionNode::create(PNK_NAME, &parser);
if (!fn)
return false;
fn->pn_body = NULL;
fn->pn_cookie.makeFree();
ParseNode *argsbody = ListNode::create(PNK_ARGSBODY, &parser);
if (!argsbody)
return false;
argsbody->setOp(JSOP_NOP);
argsbody->makeEmpty();
fn->pn_body = argsbody;
for (unsigned i = 0; i < formals.length(); i++) {
if (!DefineArg(&parser, fn, formals[i]))
return false;
}
/*
* After we're done parsing, we must fold constants, analyze any nested
* functions, and generate code for this function, including a stop opcode
* at the end.
*/
ParseNode *pn = parser.functionBody(Parser::StatementListBody);
if (!pn)
return false;
if (!parser.tokenStream.matchToken(TOK_EOF)) {
parser.reportError(NULL, JSMSG_SYNTAX_ERROR);
return false;
}
if (!FoldConstants(cx, pn, &parser))
return false;
Rooted<JSScript*> script(cx, JSScript::Create(cx, NullPtr(), false, options,
staticLevel, ss, 0, length));
if (!script)
return false;
if (!funpc.generateFunctionBindings(cx, &script->bindings))
return false;
BytecodeEmitter funbce(/* parent = */ NULL, &parser, &funsc, script, /* callerFrame = */ NULL,
/* hasGlobalScope = */ false, options.lineno);
if (!funbce.init())
return false;
if (!NameFunctions(cx, pn))
return false;
if (fn->pn_body) {
JS_ASSERT(fn->pn_body->isKind(PNK_ARGSBODY));
fn->pn_body->append(pn);
fn->pn_body->pn_pos = pn->pn_pos;
pn = fn->pn_body;
}
if (!SetSourceMap(cx, parser.tokenStream, ss, script))
return false;
//.........这里部分代码省略.........
示例6: parser
/*
* Compile a JS function body, which might appear as the value of an event
* handler attribute in an HTML <INPUT> tag.
*/
bool
frontend::CompileFunctionBody(JSContext *cx, JSFunction *fun,
JSPrincipals *principals, JSPrincipals *originPrincipals,
Bindings *bindings, const jschar *chars, size_t length,
const char *filename, unsigned lineno, JSVersion version)
{
Parser parser(cx, principals, originPrincipals, chars, length, filename, lineno, version,
/* callerFrame = */ NULL, /* foldConstants = */ true,
/* compileAndGo = */ false);
if (!parser.init())
return false;
JS_ASSERT(fun);
SharedContext funsc(cx, /* scopeChain = */ NULL, fun, /* funbox = */ NULL);
unsigned staticLevel = 0;
TreeContext funtc(&parser, &funsc, staticLevel);
if (!funtc.init())
return false;
GlobalObject *globalObject = fun->getParent() ? &fun->getParent()->global() : NULL;
Rooted<JSScript*> script(cx);
script = JSScript::Create(cx, /* savedCallerFun = */ false, principals, originPrincipals,
/* compileAndGo = */ false, /* noScriptRval = */ false,
globalObject, version, staticLevel);
if (!script)
return false;
BytecodeEmitter funbce(&parser, &funsc, script, lineno);
if (!funbce.init())
return false;
funsc.bindings.transfer(cx, bindings);
fun->setArgCount(funsc.bindings.numArgs());
if (!GenerateBlockId(&funsc, funsc.bodyid))
return false;
/* FIXME: make Function format the source for a function definition. */
ParseNode *fn = FunctionNode::create(PNK_NAME, &parser);
if (fn) {
fn->pn_body = NULL;
fn->pn_cookie.makeFree();
ParseNode *argsbody = ListNode::create(PNK_ARGSBODY, &parser);
if (!argsbody)
return false;
argsbody->setOp(JSOP_NOP);
argsbody->makeEmpty();
fn->pn_body = argsbody;
unsigned nargs = fun->nargs;
if (nargs) {
/*
* NB: do not use AutoLocalNameArray because it will release space
* allocated from cx->tempLifoAlloc by DefineArg.
*/
BindingNames names(cx);
if (!funsc.bindings.getLocalNameArray(cx, &names)) {
fn = NULL;
} else {
for (unsigned i = 0; i < nargs; i++) {
if (!DefineArg(fn, names[i].maybeAtom, i, &parser)) {
fn = NULL;
break;
}
}
}
}
}
/*
* After we're done parsing, we must fold constants, analyze any nested
* functions, and generate code for this function, including a stop opcode
* at the end.
*/
ParseNode *pn = fn ? parser.functionBody(Parser::StatementListBody) : NULL;
if (pn) {
if (!parser.tokenStream.matchToken(TOK_EOF)) {
parser.reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_SYNTAX_ERROR);
pn = NULL;
} else if (!FoldConstants(cx, pn, &parser)) {
/* FoldConstants reported the error already. */
pn = NULL;
} else if (!AnalyzeFunctions(&parser)) {
pn = NULL;
} else {
if (fn->pn_body) {
JS_ASSERT(fn->pn_body->isKind(PNK_ARGSBODY));
fn->pn_body->append(pn);
fn->pn_body->pn_pos = pn->pn_pos;
pn = fn->pn_body;
}
if (!EmitFunctionScript(cx, &funbce, pn))
pn = NULL;
}
//.........这里部分代码省略.........
示例7: CloneParseTree
/*
* Used by Parser::forStatement and comprehensionTail to clone the TARGET in
* for (var/const/let TARGET in EXPR)
*
* opn must be the pn_head of a node produced by Parser::variables, so its form
* is known to be LHS = NAME | [LHS] | {id:LHS}.
*
* The cloned tree is for use only in the same statement and binding context as
* the original tree.
*/
ParseNode *
js::CloneLeftHandSide(ParseNode *opn, Parser *parser)
{
ParseNode *pn = parser->new_<ParseNode>(opn->getKind(), opn->getOp(), opn->getArity(),
opn->pn_pos);
if (!pn)
return NULL;
pn->setInParens(opn->isInParens());
pn->setDefn(opn->isDefn());
pn->setUsed(opn->isUsed());
#if JS_HAS_DESTRUCTURING
if (opn->isArity(PN_LIST)) {
JS_ASSERT(opn->isKind(PNK_RB) || opn->isKind(PNK_RC));
pn->makeEmpty();
for (ParseNode *opn2 = opn->pn_head; opn2; opn2 = opn2->pn_next) {
ParseNode *pn2;
if (opn->isKind(PNK_RC)) {
JS_ASSERT(opn2->isArity(PN_BINARY));
JS_ASSERT(opn2->isKind(PNK_COLON));
ParseNode *tag = CloneParseTree(opn2->pn_left, parser);
if (!tag)
return NULL;
ParseNode *target = CloneLeftHandSide(opn2->pn_right, parser);
if (!target)
return NULL;
pn2 = parser->new_<BinaryNode>(PNK_COLON, JSOP_INITPROP, opn2->pn_pos, tag, target);
} else if (opn2->isArity(PN_NULLARY)) {
JS_ASSERT(opn2->isKind(PNK_COMMA));
pn2 = CloneParseTree(opn2, parser);
} else {
pn2 = CloneLeftHandSide(opn2, parser);
}
if (!pn2)
return NULL;
pn->append(pn2);
}
pn->pn_xflags = opn->pn_xflags;
return pn;
}
#endif
JS_ASSERT(opn->isArity(PN_NAME));
JS_ASSERT(opn->isKind(PNK_NAME));
/* If opn is a definition or use, make pn a use. */
pn->pn_u.name = opn->pn_u.name;
pn->setOp(JSOP_SETNAME);
if (opn->isUsed()) {
Definition *dn = pn->pn_lexdef;
pn->pn_link = dn->dn_uses;
dn->dn_uses = pn;
} else {
pn->pn_expr = NULL;
if (opn->isDefn()) {
/* We copied some definition-specific state into pn. Clear it out. */
pn->pn_cookie.makeFree();
pn->pn_dflags &= ~PND_BOUND;
pn->setDefn(false);
LinkUseToDef(pn, (Definition *) opn);
}
}
return pn;
}
示例8: switch
/*
* This function assumes the cloned tree is for use in the same statement and
* binding context as the original tree.
*/
static ParseNode *
CloneParseTree(ParseNode *opn, Parser *parser)
{
TreeContext *tc = parser->tc;
JS_CHECK_RECURSION(tc->sc->context, return NULL);
ParseNode *pn = parser->new_<ParseNode>(opn->getKind(), opn->getOp(), opn->getArity(),
opn->pn_pos);
if (!pn)
return NULL;
pn->setInParens(opn->isInParens());
pn->setDefn(opn->isDefn());
pn->setUsed(opn->isUsed());
switch (pn->getArity()) {
#define NULLCHECK(e) JS_BEGIN_MACRO if (!(e)) return NULL; JS_END_MACRO
case PN_FUNC:
NULLCHECK(pn->pn_funbox =
parser->newFunctionBox(opn->pn_funbox->object, pn, tc, opn->pn_funbox->strictModeState));
NULLCHECK(pn->pn_body = CloneParseTree(opn->pn_body, parser));
pn->pn_cookie = opn->pn_cookie;
pn->pn_dflags = opn->pn_dflags;
pn->pn_blockid = opn->pn_blockid;
break;
case PN_LIST:
pn->makeEmpty();
for (ParseNode *opn2 = opn->pn_head; opn2; opn2 = opn2->pn_next) {
ParseNode *pn2;
NULLCHECK(pn2 = CloneParseTree(opn2, parser));
pn->append(pn2);
}
pn->pn_xflags = opn->pn_xflags;
break;
case PN_TERNARY:
NULLCHECK(pn->pn_kid1 = CloneParseTree(opn->pn_kid1, parser));
NULLCHECK(pn->pn_kid2 = CloneParseTree(opn->pn_kid2, parser));
NULLCHECK(pn->pn_kid3 = CloneParseTree(opn->pn_kid3, parser));
break;
case PN_BINARY:
NULLCHECK(pn->pn_left = CloneParseTree(opn->pn_left, parser));
if (opn->pn_right != opn->pn_left)
NULLCHECK(pn->pn_right = CloneParseTree(opn->pn_right, parser));
else
pn->pn_right = pn->pn_left;
pn->pn_pval = opn->pn_pval;
pn->pn_iflags = opn->pn_iflags;
break;
case PN_UNARY:
NULLCHECK(pn->pn_kid = CloneParseTree(opn->pn_kid, parser));
pn->pn_hidden = opn->pn_hidden;
break;
case PN_NAME:
// PN_NAME could mean several arms in pn_u, so copy the whole thing.
pn->pn_u = opn->pn_u;
if (opn->isUsed()) {
/*
* The old name is a use of its pn_lexdef. Make the clone also be a
* use of that definition.
*/
Definition *dn = pn->pn_lexdef;
pn->pn_link = dn->dn_uses;
dn->dn_uses = pn;
} else if (opn->pn_expr) {
NULLCHECK(pn->pn_expr = CloneParseTree(opn->pn_expr, parser));
/*
* If the old name is a definition, the new one has pn_defn set.
* Make the old name a use of the new node.
*/
if (opn->isDefn()) {
opn->setDefn(false);
LinkUseToDef(opn, (Definition *) pn);
}
}
break;
case PN_NAMESET:
pn->pn_names = opn->pn_names;
NULLCHECK(pn->pn_tree = CloneParseTree(opn->pn_tree, parser));
break;
case PN_NULLARY:
// Even PN_NULLARY may have data (xmlpi for E4X -- what a botch).
pn->pn_u = opn->pn_u;
break;
#undef NULLCHECK
}
//.........这里部分代码省略.........