本文整理汇总了C++中Identifier类的典型用法代码示例。如果您正苦于以下问题:C++ Identifier类的具体用法?C++ Identifier怎么用?C++ Identifier使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Identifier类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: error
Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
{
int errors = 0;
//printf("StructInitializer::semantic(t = %s) %s\n", t->toChars(), toChars());
vars.setDim(field.dim);
t = t->toBasetype();
if (t->ty == Tstruct)
{
unsigned fieldi = 0;
TypeStruct *ts = (TypeStruct *)t;
ad = ts->sym;
if (ad->ctor)
error(loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead",
ad->kind(), ad->toChars(), ad->toChars());
size_t nfields = ad->fields.dim;
if (((StructDeclaration *)ad)->isnested) nfields--;
for (size_t i = 0; i < field.dim; i++)
{
Identifier *id = field.tdata()[i];
Initializer *val = value.tdata()[i];
Dsymbol *s;
VarDeclaration *v;
if (id == NULL)
{
if (fieldi >= nfields)
{ error(loc, "too many initializers for %s", ad->toChars());
errors = 1;
field.remove(i);
i--;
continue;
}
else
{
s = ad->fields.tdata()[fieldi];
}
}
else
{
//s = ad->symtab->lookup(id);
s = ad->search(loc, id, 0);
if (!s)
{
error(loc, "'%s' is not a member of '%s'", id->toChars(), t->toChars());
errors = 1;
continue;
}
// Find out which field index it is
for (fieldi = 0; 1; fieldi++)
{
if (fieldi >= nfields)
{
error(loc, "%s.%s is not a per-instance initializable field",
t->toChars(), s->toChars());
errors = 1;
break;
}
if (s == ad->fields.tdata()[fieldi])
break;
}
}
if (s && (v = s->isVarDeclaration()) != NULL)
{
val = val->semantic(sc, v->type, needInterpret);
value.tdata()[i] = val;
vars.tdata()[i] = v;
}
else
{ error(loc, "%s is not a field of %s", id ? id->toChars() : s->toChars(), ad->toChars());
errors = 1;
}
fieldi++;
}
}
else if (t->ty == Tdelegate && value.dim == 0)
{ /* Rewrite as empty delegate literal { }
*/
Parameters *arguments = new Parameters;
Type *tf = new TypeFunction(arguments, NULL, 0, LINKd);
FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, 0, tf, TOKdelegate, NULL);
fd->fbody = new CompoundStatement(loc, new Statements());
fd->endloc = loc;
Expression *e = new FuncExp(loc, fd);
ExpInitializer *ie = new ExpInitializer(loc, e);
return ie->semantic(sc, t, needInterpret);
}
else
{
error(loc, "a struct is not a valid initializer for a %s", t->toChars());
errors = 1;
}
if (errors)
{
field.setDim(0);
value.setDim(0);
vars.setDim(0);
}
//.........这里部分代码省略.........
示例2: put
size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
{
ASSERT(!propertyName.isNull());
ASSERT(get(propertyName) == notFound);
checkConsistency();
if (attributes & DontEnum)
m_hasNonEnumerableProperties = true;
UString::Rep* rep = propertyName._ustring.rep();
if (!m_propertyTable)
createPropertyMapHashTable();
// FIXME: Consider a fast case for tables with no deleted sentinels.
unsigned i = rep->existingHash();
unsigned k = 0;
bool foundDeletedElement = false;
unsigned deletedElementIndex = 0; // initialize to make the compiler happy
#if DUMP_PROPERTYMAP_STATS
++numProbes;
#endif
while (1) {
unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
if (entryIndex == emptyEntryIndex)
break;
if (entryIndex == deletedSentinelIndex) {
// If we find a deleted-element sentinel, remember it for use later.
if (!foundDeletedElement) {
foundDeletedElement = true;
deletedElementIndex = i;
}
}
if (k == 0) {
k = 1 | doubleHash(rep->existingHash());
#if DUMP_PROPERTYMAP_STATS
++numCollisions;
#endif
}
i += k;
#if DUMP_PROPERTYMAP_STATS
++numRehashes;
#endif
}
// Figure out which entry to use.
unsigned entryIndex = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount + 2;
if (foundDeletedElement) {
i = deletedElementIndex;
--m_propertyTable->deletedSentinelCount;
// Since we're not making the table bigger, we can't use the entry one past
// the end that we were planning on using, so search backwards for the empty
// slot that we can use. We know it will be there because we did at least one
// deletion in the past that left an entry empty.
while (m_propertyTable->entries()[--entryIndex - 1].key) { }
}
// Create a new hash table entry.
m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = entryIndex;
// Create a new hash table entry.
rep->ref();
m_propertyTable->entries()[entryIndex - 1].key = rep;
m_propertyTable->entries()[entryIndex - 1].attributes = attributes;
m_propertyTable->entries()[entryIndex - 1].specificValue = specificValue;
m_propertyTable->entries()[entryIndex - 1].index = ++m_propertyTable->lastIndexUsed;
unsigned newOffset;
if (m_propertyTable->deletedOffsets && !m_propertyTable->deletedOffsets->isEmpty()) {
newOffset = m_propertyTable->deletedOffsets->last();
m_propertyTable->deletedOffsets->removeLast();
} else
newOffset = m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount;
m_propertyTable->entries()[entryIndex - 1].offset = newOffset;
++m_propertyTable->keyCount;
if ((m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount) * 2 >= m_propertyTable->size)
expandPropertyMapHashTable();
checkConsistency();
return newOffset;
}
示例3: PackageDeclaration
AST::AST(){
root = new PackageDeclaration(NULL, NULL, SourceLocation(), DeclarationQualifier());
Identifier *id = root->getScope()->getInScope("__root");
id->addDeclaration(root, Identifier::ID_PACKAGE);
root->identifier = id; //XXX bit hacky
}
示例4: getOwnPropertyDescriptor
bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
// Never allow cross-domain getOwnPropertyDescriptor
if (!allowsAccessFrom(exec))
return false;
const HashEntry* entry;
// We don't want any properties other than "close" and "closed" on a closed window.
if (!impl()->frame()) {
// The following code is safe for cross-domain and same domain use.
// It ignores any custom properties that might be set on the DOMWindow (including a custom prototype).
entry = s_info.propHashTable(exec)->entry(exec, propertyName);
if (entry && !(entry->attributes() & Function) && entry->propertyGetter() == jsDOMWindowClosed) {
descriptor.setDescriptor(jsBoolean(true), ReadOnly | DontDelete | DontEnum);
return true;
}
entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName);
if (entry && (entry->attributes() & Function) && entry->function() == jsDOMWindowPrototypeFunctionClose) {
PropertySlot slot;
slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>);
descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum);
return true;
}
descriptor.setUndefined();
return true;
}
entry = JSDOMWindow::s_info.propHashTable(exec)->entry(exec, propertyName);
if (entry) {
PropertySlot slot;
slot.setCustom(this, entry->propertyGetter());
descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes());
return true;
}
// Check for child frames by name before built-in properties to
// match Mozilla. This does not match IE, but some sites end up
// naming frames things that conflict with window properties that
// are in Moz but not IE. Since we have some of these, we have to do
// it the Moz way.
if (impl()->frame()->tree()->child(identifierToAtomicString(propertyName))) {
PropertySlot slot;
slot.setCustom(this, childFrameGetter);
descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum);
return true;
}
bool ok;
unsigned i = propertyName.toArrayIndex(ok);
if (ok && i < impl()->frame()->tree()->childCount()) {
PropertySlot slot;
slot.setCustomIndex(this, i, indexGetter);
descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum);
return true;
}
// Allow shortcuts like 'Image1' instead of document.images.Image1
Document* document = impl()->frame()->document();
if (document->isHTMLDocument()) {
AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName);
if (atomicPropertyName && (static_cast<HTMLDocument*>(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) {
PropertySlot slot;
slot.setCustom(this, namedItemGetter);
descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum);
return true;
}
}
return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
}
示例5: printf
//.........这里部分代码省略.........
{
return isFuncX(e, &isFuncOverrideFunction);
}
else if (e->ident == Id::isStaticFunction)
{
return isFuncX(e, &isFuncStaticFunction);
}
else if (e->ident == Id::isRef)
{
return isDeclX(e, &isDeclRef);
}
else if (e->ident == Id::isOut)
{
return isDeclX(e, &isDeclOut);
}
else if (e->ident == Id::isLazy)
{
return isDeclX(e, &isDeclLazy);
}
else if (e->ident == Id::identifier)
{
// Get identifier for symbol as a string literal
/* Specify 0 for bit 0 of the flags argument to semanticTiargs() so that
* a symbol should not be folded to a constant.
* Bit 1 means don't convert Parameter to Type if Parameter has an identifier
*/
if (!TemplateInstance::semanticTiargs(e->loc, sc, e->args, 2))
return new ErrorExp();
if (dim != 1)
goto Ldimerror;
RootObject *o = (*e->args)[0];
Parameter *po = isParameter(o);
Identifier *id;
if (po)
{
id = po->ident;
assert(id);
}
else
{
Dsymbol *s = getDsymbol(o);
if (!s || !s->ident)
{
e->error("argument %s has no identifier", o->toChars());
goto Lfalse;
}
id = s->ident;
}
StringExp *se = new StringExp(e->loc, id->toChars());
return se->semantic(sc);
}
else if (e->ident == Id::getProtection)
{
if (dim != 1)
goto Ldimerror;
Scope *sc2 = sc->push();
sc2->flags = sc->flags | SCOPEnoaccesscheck;
bool ok = TemplateInstance::semanticTiargs(e->loc, sc2, e->args, 1);
sc2->pop();
if (!ok)
return new ErrorExp();
RootObject *o = (*e->args)[0];
示例6: Module
Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
{
//printf("Module::load(ident = '%s')\n", ident->toChars());
// Build module filename by turning:
// foo.bar.baz
// into:
// foo\bar\baz
char *filename = ident->toChars();
if (packages && packages->dim)
{
OutBuffer buf;
for (size_t i = 0; i < packages->dim; i++)
{ Identifier *pid = (*packages)[i];
buf.writestring(pid->toChars());
#if _WIN32
buf.writeByte('\\');
#else
buf.writeByte('/');
#endif
}
buf.writestring(filename);
buf.writeByte(0);
filename = (char *)buf.extractData();
}
Module *m = new Module(filename, ident, 0, 0);
m->loc = loc;
/* Look for the source file
*/
const char *result = lookForSourceFile(filename);
if (result)
m->srcfile = new File(result);
if (global.params.verbose)
{
fprintf(global.stdmsg, "import ");
if (packages)
{
for (size_t i = 0; i < packages->dim; i++)
{
Identifier *pid = (*packages)[i];
fprintf(global.stdmsg, "%s.", pid->toChars());
}
}
fprintf(global.stdmsg, "%s\t(%s)\n", ident->toChars(), m->srcfile->toChars());
}
if (!m->read(loc))
return NULL;
m->parse();
#ifdef IN_GCC
d_gcc_magic_module(m);
#endif
return m;
}
示例7: identifierToJSValue
static JSValue identifierToJSValue(VM& vm, const Identifier& identifier)
{
if (identifier.isSymbol())
return Symbol::create(vm, static_cast<SymbolImpl&>(*identifier.impl()));
return jsString(&vm, identifier.impl());
}
示例8: DtoCheckPragma
void DtoCheckPragma(PragmaDeclaration *decl, Dsymbol *s,
Pragma llvm_internal, const std::string &arg1str)
{
if (llvm_internal == LLVMnone || llvm_internal == LLVMignore)
return;
if (s->llvmInternal)
{
error(Loc(), "multiple LDC specific pragmas not allowed not affect the same "
"declaration ('%s' at '%s')", s->toChars(), s->loc.toChars());
fatal();
}
Identifier *ident = decl->ident;
switch(llvm_internal)
{
case LLVMintrinsic:
if (FuncDeclaration* fd = s->isFuncDeclaration())
{
fd->llvmInternal = llvm_internal;
fd->intrinsicName = arg1str;
fd->mangleOverride = strdup(fd->intrinsicName.c_str());
}
else if (TemplateDeclaration* td = s->isTemplateDeclaration())
{
td->llvmInternal = llvm_internal;
td->intrinsicName = arg1str;
}
else
{
error(s->loc, "the '%s' pragma is only allowed on function or template declarations",
ident->toChars());
fatal();
}
break;
case LLVMglobal_crt_ctor:
case LLVMglobal_crt_dtor:
if (FuncDeclaration* fd = s->isFuncDeclaration())
{
assert(fd->type->ty == Tfunction);
TypeFunction* type = static_cast<TypeFunction*>(fd->type);
Type* retType = type->next;
if (retType->ty != Tvoid || type->parameters->dim > 0 || (
fd->isAggregateMember()
&& !fd->isStatic())) {
error(s->loc, "the '%s' pragma is only allowed on void functions which take no arguments",
ident->toChars());
fd->llvmInternal = LLVMnone;
break;
}
fd->llvmInternal = llvm_internal;
fd->priority = std::atoi(arg1str.c_str());
}
else
{
error(s->loc, "the '%s' pragma is only allowed on function declarations",
ident->toChars());
s->llvmInternal = LLVMnone;
}
break;
case LLVMatomic_rmw:
if (TemplateDeclaration* td = s->isTemplateDeclaration())
{
td->llvmInternal = llvm_internal;
td->intrinsicName = arg1str;
}
else
{
error(s->loc, "the '%s' pragma is only allowed on template declarations",
ident->toChars());
fatal();
}
break;
case LLVMva_start:
case LLVMva_arg:
case LLVMatomic_load:
case LLVMatomic_store:
case LLVMatomic_cmp_xchg:
if (TemplateDeclaration* td = s->isTemplateDeclaration())
{
if (td->parameters->dim != 1)
{
error(s->loc, "the '%s' pragma template must have exactly one template parameter",
ident->toChars());
fatal();
}
else if (!td->onemember)
{
error(s->loc, "the '%s' pragma template must have exactly one member",
ident->toChars());
fatal();
}
else if (td->overnext || td->overroot)
{
error(s->loc, "the '%s' pragma template must not be overloaded",
//.........这里部分代码省略.........
示例9: finishCreation
void JSFunction::finishCreation(ExecState* exec, NativeExecutable* executable, int length, const Identifier& name)
{
Base::finishCreation(exec->globalData());
ASSERT(inherits(&s_info));
m_executable.set(exec->globalData(), this, executable);
putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
}
示例10: RenameIdent
void Converter::RenameIdent(Identifier& ident)
{
ident.AppendPrefix(nameMangling_.temporaryPrefix);
}
示例11: Module
Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
{ Module *m;
char *filename;
//printf("Module::load(ident = '%s')\n", ident->toChars());
// Build module filename by turning:
// foo.bar.baz
// into:
// foo\bar\baz
filename = ident->toChars();
if (packages && packages->dim)
{
OutBuffer buf;
for (size_t i = 0; i < packages->dim; i++)
{ Identifier *pid = packages->tdata()[i];
buf.writestring(pid->toChars());
#if _WIN32
buf.writeByte('\\');
#else
buf.writeByte('/');
#endif
}
buf.writestring(filename);
buf.writeByte(0);
filename = (char *)buf.extractData();
}
m = new Module(filename, ident, 0, 0);
m->loc = loc;
/* Search along global.path for .di file, then .d file.
*/
char *result = NULL;
FileName *fdi = FileName::forceExt(filename, global.hdr_ext);
FileName *fd = FileName::forceExt(filename, global.mars_ext);
char *sdi = fdi->toChars();
char *sd = fd->toChars();
if (FileName::exists(sdi))
result = sdi;
else if (FileName::exists(sd))
result = sd;
else if (FileName::absolute(filename))
;
else if (!global.path)
;
else
{
for (size_t i = 0; i < global.path->dim; i++)
{
char *p = global.path->tdata()[i];
char *n = FileName::combine(p, sdi);
if (FileName::exists(n))
{ result = n;
break;
}
mem.free(n);
n = FileName::combine(p, sd);
if (FileName::exists(n))
{ result = n;
break;
}
mem.free(n);
}
}
if (result)
m->srcfile = new File(result);
if (global.params.verbose)
{
printf("import ");
if (packages)
{
for (size_t i = 0; i < packages->dim; i++)
{ Identifier *pid = packages->tdata()[i];
printf("%s.", pid->toChars());
}
}
printf("%s\t(%s)\n", ident->toChars(), m->srcfile->toChars());
}
m->read(loc);
m->parse();
#ifdef IN_GCC
d_gcc_magic_module(m);
#endif
return m;
}
示例12: DtoCheckPragma
void DtoCheckPragma(PragmaDeclaration *decl, Dsymbol *s,
Pragma llvm_internal, const std::string &arg1str)
{
if (llvm_internal == LLVMnone || llvm_internal == LLVMignore)
return;
if (s->llvmInternal)
{
error("multiple LDC specific pragmas not allowed not affect the same "
"declaration ('%s' at '%s')", s->toChars(), s->loc.toChars());
fatal();
}
Identifier *ident = decl->ident;
switch(llvm_internal)
{
case LLVMintrinsic:
if (FuncDeclaration* fd = s->isFuncDeclaration())
{
fd->llvmInternal = llvm_internal;
fd->intrinsicName = arg1str;
fd->linkage = LINKintrinsic;
static_cast<TypeFunction*>(fd->type)->linkage = LINKintrinsic;
}
else if (TemplateDeclaration* td = s->isTemplateDeclaration())
{
td->llvmInternal = llvm_internal;
td->intrinsicName = arg1str;
}
else
{
error("only allowed on function declarations");
fatal();
}
break;
case LLVMglobal_crt_ctor:
case LLVMglobal_crt_dtor:
if (FuncDeclaration* fd = s->isFuncDeclaration())
{
assert(fd->type->ty == Tfunction);
TypeFunction* type = static_cast<TypeFunction*>(fd->type);
Type* retType = type->next;
if (retType->ty != Tvoid || type->parameters->dim > 0 || (
#if DMDV2
fd->isAggregateMember()
#else
fd->isThis()
#endif
&& !fd->isStatic())) {
error(fd->loc, "the '%s' pragma is only allowed on void functions which take no arguments",
ident->toChars());
fd->llvmInternal = LLVMnone;
break;
}
fd->llvmInternal = llvm_internal;
fd->priority = std::atoi(arg1str.c_str());
}
else
{
error(s->loc, "the '%s' pragma is only allowed on function declarations",
ident->toChars());
s->llvmInternal = LLVMnone;
}
break;
case LLVMatomic_rmw:
if (TemplateDeclaration* td = s->isTemplateDeclaration())
{
td->llvmInternal = llvm_internal;
td->intrinsicName = arg1str;
}
else
{
error("the '%s' pragma is only allowed on template declarations",
ident->toChars());
fatal();
}
break;
case LLVMva_start:
case LLVMva_arg:
case LLVMatomic_load:
case LLVMatomic_store:
case LLVMatomic_cmp_xchg:
if (TemplateDeclaration* td = s->isTemplateDeclaration())
{
if (td->parameters->dim != 1)
{
error("the '%s' pragma template must have exactly one template parameter",
ident->toChars());
fatal();
}
else if (!td->onemember)
{
error("the '%s' pragma template must have exactly one member",
ident->toChars());
fatal();
}
//.........这里部分代码省略.........
示例13: JSObject
InternalFunction::InternalFunction(JSGlobalData* globalData, PassRefPtr<Structure> structure, const Identifier& name)
: JSObject(structure)
{
putDirect(globalData->propertyNames->name, jsString(globalData, name.ustring()), DontDelete | ReadOnly | DontEnum);
}
示例14: Expressions
/***************************************
* This works by transforming a struct initializer into
* a struct literal. In the future, the two should be the
* same thing.
*/
Expression *StructInitializer::toExpression()
{ Expression *e;
size_t offset;
//printf("StructInitializer::toExpression() %s\n", toChars());
if (!ad) // if fwd referenced
{
return NULL;
}
StructDeclaration *sd = ad->isStructDeclaration();
if (!sd)
return NULL;
Expressions *elements = new Expressions();
size_t nfields = ad->fields.dim;
#if DMDV2
if (sd->isnested)
nfields--;
#endif
elements->setDim(nfields);
for (size_t i = 0; i < elements->dim; i++)
{
elements->tdata()[i] = NULL;
}
unsigned fieldi = 0;
for (size_t i = 0; i < value.dim; i++)
{
Identifier *id = field.tdata()[i];
if (id)
{
Dsymbol * s = ad->search(loc, id, 0);
if (!s)
{
error(loc, "'%s' is not a member of '%s'", id->toChars(), sd->toChars());
goto Lno;
}
// Find out which field index it is
for (fieldi = 0; 1; fieldi++)
{
if (fieldi >= nfields)
{
s->error("is not a per-instance initializable field");
goto Lno;
}
if (s == ad->fields.tdata()[fieldi])
break;
}
}
else if (fieldi >= nfields)
{ error(loc, "too many initializers for '%s'", ad->toChars());
goto Lno;
}
Initializer *iz = value.tdata()[i];
if (!iz)
goto Lno;
Expression *ex = iz->toExpression();
if (!ex)
goto Lno;
if (elements->tdata()[fieldi])
{ error(loc, "duplicate initializer for field '%s'",
ad->fields.tdata()[fieldi]->toChars());
goto Lno;
}
elements->tdata()[fieldi] = ex;
++fieldi;
}
// Now, fill in any missing elements with default initializers.
// We also need to validate any anonymous unions
offset = 0;
for (size_t i = 0; i < elements->dim; )
{
VarDeclaration * vd = ad->fields.tdata()[i]->isVarDeclaration();
//printf("test2 [%d] : %s %d %d\n", i, vd->toChars(), (int)offset, (int)vd->offset);
if (vd->offset < offset)
{
// Only the first field of a union can have an initializer
if (elements->tdata()[i])
goto Lno;
}
else
{
if (!elements->tdata()[i])
// Default initialize
elements->tdata()[i] = vd->type->defaultInit();
}
offset = vd->offset + vd->type->size();
i++;
#if 0
int unionSize = ad->numFieldsInUnion(i);
if (unionSize == 1)
{ // Not a union -- default initialize if missing
if (!elements->tdata()[i])
elements->tdata()[i] = vd->type->defaultInit();
}
//.........这里部分代码省略.........
示例15: parseFunctionArguments
/// Parse a function definition signature.
/// func-signature:
/// func-arguments func-throws? func-signature-result?
/// func-signature-result:
/// '->' type
///
/// Note that this leaves retType as null if unspecified.
ParserStatus
Parser::parseFunctionSignature(Identifier SimpleName,
DeclName &FullName,
SmallVectorImpl<ParameterList*> &bodyParams,
DefaultArgumentInfo &defaultArgs,
SourceLoc &throwsLoc,
bool &rethrows,
TypeRepr *&retType) {
SmallVector<Identifier, 4> NamePieces;
NamePieces.push_back(SimpleName);
FullName = SimpleName;
ParserStatus Status;
// We force first type of a func declaration to be a tuple for consistency.
if (Tok.is(tok::l_paren)) {
ParameterContextKind paramContext;
if (SimpleName.isOperator())
paramContext = ParameterContextKind::Operator;
else
paramContext = ParameterContextKind::Function;
Status = parseFunctionArguments(NamePieces, bodyParams, paramContext,
defaultArgs);
FullName = DeclName(Context, SimpleName,
llvm::makeArrayRef(NamePieces.begin() + 1,
NamePieces.end()));
if (bodyParams.empty()) {
// If we didn't get anything, add a () pattern to avoid breaking
// invariants.
assert(Status.hasCodeCompletion() || Status.isError());
bodyParams.push_back(ParameterList::createEmpty(Context));
}
} else {
diagnose(Tok, diag::func_decl_without_paren);
Status = makeParserError();
// Recover by creating a '() -> ?' signature.
bodyParams.push_back(ParameterList::createEmpty(Context, PreviousLoc,
PreviousLoc));
FullName = DeclName(Context, SimpleName, bodyParams.back());
}
// Check for the 'throws' keyword.
rethrows = false;
if (Tok.is(tok::kw_throws)) {
throwsLoc = consumeToken();
} else if (Tok.is(tok::kw_rethrows)) {
throwsLoc = consumeToken();
rethrows = true;
} else if (Tok.is(tok::kw_throw)) {
throwsLoc = consumeToken();
diagnose(throwsLoc, diag::throw_in_function_type)
.fixItReplace(throwsLoc, "throws");
}
SourceLoc arrowLoc;
// If there's a trailing arrow, parse the rest as the result type.
if (Tok.isAny(tok::arrow, tok::colon)) {
if (!consumeIf(tok::arrow, arrowLoc)) {
// FixIt ':' to '->'.
diagnose(Tok, diag::func_decl_expected_arrow)
.fixItReplace(SourceRange(Tok.getLoc()), "->");
arrowLoc = consumeToken(tok::colon);
}
ParserResult<TypeRepr> ResultType =
parseType(diag::expected_type_function_result);
if (ResultType.hasCodeCompletion())
return ResultType;
retType = ResultType.getPtrOrNull();
if (!retType) {
Status.setIsParseError();
return Status;
}
} else {
// Otherwise, we leave retType null.
retType = nullptr;
}
// Check for 'throws' and 'rethrows' after the type and correct it.
if (!throwsLoc.isValid()) {
if (Tok.is(tok::kw_throws)) {
throwsLoc = consumeToken();
} else if (Tok.is(tok::kw_rethrows)) {
throwsLoc = consumeToken();
rethrows = true;
}
if (throwsLoc.isValid()) {
assert(arrowLoc.isValid());
assert(retType);
auto diag = rethrows ? diag::rethrows_after_function_result
//.........这里部分代码省略.........