本文整理汇总了C++中StringExp类的典型用法代码示例。如果您正苦于以下问题:C++ StringExp类的具体用法?C++ StringExp怎么用?C++ StringExp使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了StringExp类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: resolveProperties
void CompileDeclaration::compileIt(Scope *sc)
{
//printf("CompileDeclaration::compileIt(loc = %d) %s\n", loc.linnum, exp->toChars());
sc = sc->startCTFE();
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
sc = sc->endCTFE();
if (exp->op != TOKerror)
{
Expression *e = exp->ctfeInterpret();
StringExp *se = e->toStringExp();
if (!se)
exp->error("argument to mixin must be a string, not (%s) of type %s", exp->toChars(), exp->type->toChars());
else
{
se = se->toUTF8(sc);
unsigned errors = global.errors;
Parser p(loc, sc->module, (utf8_t *)se->string, se->len, 0);
p.nextToken();
decl = p.parseDeclDefs(0);
if (p.token.value != TOKeof)
exp->error("incomplete mixin declaration (%s)", se->toChars());
if (p.errors)
{
assert(global.errors != errors);
decl = NULL;
}
}
}
}
示例2: String2
String2(const StringExp<S,L,R>& exp)
: mdata(exp.size() + 1)
{
S* dest = mdata.GetArray();
exp.append(dest);
*dest = 0;
}
示例3: resolveProperties
Initializer *ExpInitializer::semantic(Scope *sc, Type *t, int needInterpret)
{
//printf("ExpInitializer::semantic(%s), type = %s\n", exp->toChars(), t->toChars());
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
int wantOptimize = needInterpret ? WANTinterpret|WANTvalue : WANTvalue;
int olderrors = global.errors;
exp = exp->optimize(wantOptimize);
if (!global.gag && olderrors != global.errors)
return this; // Failed, suppress duplicate error messages
if (exp->op == TOKtype)
exp->error("initializer must be an expression, not '%s'", exp->toChars());
// Make sure all pointers are constants
if (needInterpret && hasNonConstPointers(exp))
{
exp->error("cannot use non-constant CTFE pointer in an initializer '%s'", exp->toChars());
return this;
}
Type *tb = t->toBasetype();
/* Look for case of initializing a static array with a too-short
* string literal, such as:
* char[5] foo = "abc";
* Allow this by doing an explicit cast, which will lengthen the string
* literal.
*/
if (exp->op == TOKstring && tb->ty == Tsarray && exp->type->ty == Tsarray)
{ StringExp *se = (StringExp *)exp;
if (!se->committed && se->type->ty == Tsarray &&
((TypeSArray *)se->type)->dim->toInteger() <
((TypeSArray *)t)->dim->toInteger())
{
exp = se->castTo(sc, t);
goto L1;
}
}
// Look for the case of statically initializing an array
// with a single member.
if (tb->ty == Tsarray &&
!tb->nextOf()->equals(exp->type->toBasetype()->nextOf()) &&
exp->implicitConvTo(tb->nextOf())
)
{
t = tb->nextOf();
}
exp = exp->implicitCastTo(sc, t);
L1:
exp = exp->optimize(wantOptimize);
//printf("-ExpInitializer::semantic(): "); exp->print();
return this;
}
示例4: resolveProperties
Initializer *ExpInitializer::semantic(Scope *sc, Type *t)
{
//printf("ExpInitializer::semantic(%s), type = %s\n", exp->toChars(), t->toChars());
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
exp = exp->optimize(WANTvalue | WANTinterpret);
Type *tb = t->toBasetype();
/* Look for case of initializing a static array with a too-short
* string literal, such as:
* char[5] foo = "abc";
* Allow this by doing an explicit cast, which will lengthen the string
* literal.
*/
if (exp->op == TOKstring && tb->ty == Tsarray && exp->type->ty == Tsarray)
{ StringExp *se = (StringExp *)exp;
if (!se->committed && se->type->ty == Tsarray &&
((TypeSArray *)se->type)->dim->toInteger() <
((TypeSArray *)t)->dim->toInteger())
{
exp = se->castTo(sc, t);
goto L1;
}
}
// Look for the case of statically initializing an array
// with a single member.
if (tb->ty == Tsarray &&
!tb->nextOf()->equals(exp->type->toBasetype()->nextOf()) &&
exp->implicitConvTo(tb->nextOf())
)
{
t = tb->nextOf();
}
exp = exp->implicitCastTo(sc, t);
L1:
exp = exp->optimize(WANTvalue | WANTinterpret);
//printf("-ExpInitializer::semantic(): "); exp->print();
return this;
}
示例5: resolveProperties
void CompileDeclaration::compileIt(Scope *sc)
{
//printf("CompileDeclaration::compileIt(loc = %d) %s\n", loc.linnum, exp->toChars());
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
exp = exp->ctfeInterpret();
StringExp *se = exp->toString();
if (!se)
{ exp->error("argument to mixin must be a string, not (%s)", exp->toChars());
}
else
{
se = se->toUTF8(sc);
Parser p(sc->module, (unsigned char *)se->string, se->len, 0);
p.loc = loc;
p.nextToken();
decl = p.parseDeclDefs(0);
if (p.token.value != TOKeof)
exp->error("incomplete mixin declaration (%s)", se->toChars());
}
}
示例6: resolveProperties
void CompileDeclaration::compileIt(Scope *sc)
{
//printf("CompileDeclaration::compileIt(loc = %d)\n", loc.linnum);
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
exp = exp->optimize(WANTvalue | WANTinterpret);
if (exp->op != TOKstring)
{ /* exp->error("argument to mixin must be a string, not (%s)", exp->toChars()); */
}
else
{
StringExp *se = (StringExp *)exp;
se = se->toUTF8(sc);
Parser p(sc->module, (unsigned char *)se->string, se->len, 0);
p.loc = loc;
p.nextToken();
decl = p.parseDeclDefs(0);
/* if (p.token.value != TOKeof)
exp->error("incomplete mixin declaration (%s)", se->toChars()); */
}
}
示例7: visit
void visit(PragmaDeclaration *pd)
{
if (pd->ident == Id::lib)
{
assert(pd->args && pd->args->dim == 1);
Expression *e = (*pd->args)[0];
assert(e->op == TOKstring);
StringExp *se = (StringExp *)e;
char *name = (char *)mem.xmalloc(se->numberOfCodeUnits() + 1);
se->writeTo(name, true);
/* Embed the library names into the object file.
* The linker will then automatically
* search that library, too.
*/
if (!obj_includelib(name))
{
/* The format does not allow embedded library names,
* so instead append the library name to the list to be passed
* to the linker.
*/
global.params.libfiles->push(name);
}
}
else if (pd->ident == Id::startaddress)
{
assert(pd->args && pd->args->dim == 1);
Expression *e = (*pd->args)[0];
Dsymbol *sa = getDsymbol(e);
FuncDeclaration *f = sa->isFuncDeclaration();
assert(f);
Symbol *s = toSymbol(f);
obj_startaddress(s);
}
visit((AttribDeclaration *)pd);
}
示例8: visit
/** \name Visit Constant Expressions nodes.
** \{ */
void PrintVisitor::visit (const StringExp &e)
{
if (types::InternalType * pIT = e.getConstant())
{
types::String * pStr = static_cast<types::String *>(pIT);
if (pStr->getSize() == 0)
{
*ostr << L"[]";
}
if (pStr->getSize() == 1)
{
std::wstring wstr(pStr->get(0, 0));
printString(wstr);
}
else
{
*ostr << L"[";
const int r = pStr->getRows();
const int c = pStr->getCols();
for (int i = 0; i < r; ++i)
{
for (int j = 0; j < c - 1; ++j)
{
std::wstring wstr(pStr->get(i, j));
printString(wstr);
*ostr << L" ";
}
std::wstring wstr(pStr->get(i, c - 1));
printString(wstr);
*ostr << L";";
}
*ostr << L"]";
}
}
else
{
printString(e.getValue());
}
}
示例9: visit
void visit(PragmaDeclaration *decl) override {
if (decl->ident == Id::lib) {
assert(decl->args && decl->args->dim == 1);
assert(!irs->dcomputetarget);
Expression *e = static_cast<Expression *>(decl->args->data[0]);
assert(e->op == TOKstring);
StringExp *se = static_cast<StringExp *>(e);
const std::string name(se->toPtr(), se->numberOfCodeUnits());
auto nameLen = name.size();
if (global.params.targetTriple->isWindowsGNUEnvironment()) {
if (nameLen > 4 && !memcmp(&name[nameLen - 4], ".lib", 4)) {
// On MinGW, strip the .lib suffix, if any, to improve
// compatibility with code written for DMD (we pass the name to GCC
// via -l, just as on Posix).
nameLen -= 4;
}
if (nameLen >= 7 && !memcmp(name.data(), "shell32", 7)) {
// Another DMD compatibility kludge: Ignore
// pragma(lib, "shell32.lib"), it is implicitly provided by
// MinGW.
return;
}
}
// With LLVM 3.3 or later we can place the library name in the object
// file. This seems to be supported only on Windows.
if (global.params.targetTriple->isWindowsMSVCEnvironment()) {
llvm::SmallString<24> LibName(name);
// Win32: /DEFAULTLIB:"curl"
if (LibName.endswith(".a")) {
LibName = LibName.substr(0, LibName.size() - 2);
}
if (LibName.endswith(".lib")) {
LibName = LibName.substr(0, LibName.size() - 4);
}
llvm::SmallString<24> tmp("/DEFAULTLIB:\"");
tmp.append(LibName);
tmp.append("\"");
LibName = tmp;
// Embed library name as linker option in object file
auto Value = llvm::MDString::get(gIR->context(), LibName);
gIR->LinkerMetadataArgs.push_back(
llvm::MDNode::get(gIR->context(), Value));
} else {
size_t const n = nameLen + 3;
char *arg = static_cast<char *>(mem.xmalloc(n));
arg[0] = '-';
arg[1] = 'l';
memcpy(arg + 2, name.data(), nameLen);
arg[n - 1] = 0;
global.params.linkswitches.push(arg);
}
}
visit(static_cast<AttribDeclaration *>(decl));
}
示例10: resolveProperties
Initializer *ExpInitializer::semantic(Scope *sc, Type *t, NeedInterpret needInterpret)
{
//printf("ExpInitializer::semantic(%s), type = %s\n", exp->toChars(), t->toChars());
if (needInterpret)
exp = exp->ctfeSemantic(sc);
else
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
if (exp->op == TOKerror)
return this;
int olderrors = global.errors;
if (needInterpret)
exp = exp->ctfeInterpret();
else
exp = exp->optimize(WANTvalue);
if (!global.gag && olderrors != global.errors)
return this; // Failed, suppress duplicate error messages
if (exp->op == TOKtype)
{
exp->error("initializer must be an expression, not '%s'", exp->toChars());
return new ErrorInitializer();
}
// Make sure all pointers are constants
if (needInterpret && hasNonConstPointers(exp))
{
exp->error("cannot use non-constant CTFE pointer in an initializer '%s'", exp->toChars());
return new ErrorInitializer();
}
Type *tb = t->toBasetype();
Type *ti = exp->type->toBasetype();
if (exp->op == TOKtuple &&
expandTuples &&
!exp->implicitConvTo(t))
return new ExpInitializer(loc, exp);
/* Look for case of initializing a static array with a too-short
* string literal, such as:
* char[5] foo = "abc";
* Allow this by doing an explicit cast, which will lengthen the string
* literal.
*/
if (exp->op == TOKstring && tb->ty == Tsarray && ti->ty == Tsarray)
{ StringExp *se = (StringExp *)exp;
if (!se->committed && se->type->ty == Tsarray &&
((TypeSArray *)se->type)->dim->toInteger() <
((TypeSArray *)t)->dim->toInteger())
{
exp = se->castTo(sc, t);
goto L1;
}
}
// Look for implicit constructor call
if (tb->ty == Tstruct &&
!(ti->ty == Tstruct && tb->toDsymbol(sc) == ti->toDsymbol(sc)) &&
!exp->implicitConvTo(t))
{
StructDeclaration *sd = ((TypeStruct *)tb)->sym;
if (sd->ctor)
{ // Rewrite as S().ctor(exp)
Expression *e;
e = new StructLiteralExp(loc, sd, NULL);
e = new DotIdExp(loc, e, Id::ctor);
e = new CallExp(loc, e, exp);
e = e->semantic(sc);
if (needInterpret)
exp = e->ctfeInterpret();
else
exp = e->optimize(WANTvalue);
}
}
// Look for the case of statically initializing an array
// with a single member.
if (tb->ty == Tsarray &&
!tb->nextOf()->equals(ti->toBasetype()->nextOf()) &&
exp->implicitConvTo(tb->nextOf())
)
{
/* If the variable is not actually used in compile time, array creation is
* redundant. So delay it until invocation of toExpression() or toDt().
*/
t = tb->nextOf();
}
exp = exp->implicitCastTo(sc, t);
if (exp->op == TOKerror)
return this;
L1:
if (needInterpret)
exp = exp->ctfeInterpret();
else
exp = exp->optimize(WANTvalue);
//printf("-ExpInitializer::semantic(): "); exp->print();
//.........这里部分代码省略.........
示例11: assert
DValue *DtoInlineAsmExpr(Loc &loc, FuncDeclaration *fd, Expressions *arguments,
LLValue *sretPointer) {
IF_LOG Logger::println("DtoInlineAsmExpr @ %s", loc.toChars());
LOG_SCOPE;
assert(fd->toParent()->isTemplateInstance() && "invalid inline __asm expr");
assert(arguments->dim >= 2 && "invalid __asm call");
// get code param
Expression *e = (*arguments)[0];
IF_LOG Logger::println("code exp: %s", e->toChars());
StringExp *se = static_cast<StringExp *>(e);
if (e->op != TOKstring || se->sz != 1) {
e->error("`__asm` code argument is not a `char[]` string literal");
fatal();
}
std::string code(se->toPtr(), se->numberOfCodeUnits());
// get constraints param
e = (*arguments)[1];
IF_LOG Logger::println("constraint exp: %s", e->toChars());
se = static_cast<StringExp *>(e);
if (e->op != TOKstring || se->sz != 1) {
e->error("`__asm` constraints argument is not a `char[]` string literal");
fatal();
}
std::string constraints(se->toPtr(), se->numberOfCodeUnits());
// build runtime arguments
size_t n = arguments->dim;
LLSmallVector<llvm::Value *, 8> args;
args.reserve(n - 2);
std::vector<LLType *> argtypes;
argtypes.reserve(n - 2);
for (size_t i = 2; i < n; i++) {
args.push_back(DtoRVal((*arguments)[i]));
argtypes.push_back(args.back()->getType());
}
// build asm function type
Type *type = fd->type->nextOf();
LLType *ret_type = DtoType(type->toBasetype());
llvm::FunctionType *FT = llvm::FunctionType::get(ret_type, argtypes, false);
// make sure the constraints are valid
if (!llvm::InlineAsm::Verify(FT, constraints)) {
e->error("`__asm` constraint argument is invalid");
fatal();
}
// build asm call
bool sideeffect = true;
llvm::InlineAsm *ia = llvm::InlineAsm::get(FT, code, constraints, sideeffect);
llvm::Value *rv = gIR->ir->CreateCall(ia, args, "");
if (sretPointer) {
DtoStore(rv, DtoBitCast(sretPointer, getPtrToType(ret_type)));
return new DLValue(type, sretPointer);
}
// work around missing tuple support for users of the return value
if (type->ty == Tstruct) {
// make a copy
llvm::Value *mem = DtoAlloca(type, ".__asm_tuple_ret");
DtoStore(rv, DtoBitCast(mem, getPtrToType(ret_type)));
return new DLValue(type, mem);
}
// return call as im value
return new DImValue(type, rv);
}
示例12: resolveProperties
Initializer *ExpInitializer::semantic(Scope *sc, Type *t, NeedInterpret needInterpret)
{
//printf("ExpInitializer::semantic(%s), type = %s\n", exp->toChars(), t->toChars());
if (needInterpret) sc = sc->startCTFE();
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
if (needInterpret) sc = sc->endCTFE();
if (exp->op == TOKerror)
return new ErrorInitializer();
unsigned int olderrors = global.errors;
if (needInterpret)
{
// If the result will be implicitly cast, move the cast into CTFE
// to avoid premature truncation of polysemous types.
// eg real [] x = [1.1, 2.2]; should use real precision.
if (exp->implicitConvTo(t))
{
exp = exp->implicitCastTo(sc, t);
}
exp = exp->ctfeInterpret();
}
else
{
exp = exp->optimize(WANTvalue);
}
if (!global.gag && olderrors != global.errors)
return this; // Failed, suppress duplicate error messages
if (exp->op == TOKtype)
{
exp->error("initializer must be an expression, not '%s'", exp->toChars());
return new ErrorInitializer();
}
// Make sure all pointers are constants
if (needInterpret && hasNonConstPointers(exp))
{
exp->error("cannot use non-constant CTFE pointer in an initializer '%s'", exp->toChars());
return new ErrorInitializer();
}
Type *tb = t->toBasetype();
Type *ti = exp->type->toBasetype();
if (exp->op == TOKtuple && expandTuples && !exp->implicitConvTo(t))
return new ExpInitializer(loc, exp);
/* Look for case of initializing a static array with a too-short
* string literal, such as:
* char[5] foo = "abc";
* Allow this by doing an explicit cast, which will lengthen the string
* literal.
*/
if (exp->op == TOKstring && tb->ty == Tsarray && ti->ty == Tsarray)
{
StringExp *se = (StringExp *)exp;
if (!se->committed && se->type->ty == Tsarray &&
((TypeSArray *)se->type)->dim->toInteger() <
((TypeSArray *)t)->dim->toInteger())
{
exp = se->castTo(sc, t);
goto L1;
}
}
// Look for implicit constructor call
if (tb->ty == Tstruct &&
!(ti->ty == Tstruct && tb->toDsymbol(sc) == ti->toDsymbol(sc)) &&
!exp->implicitConvTo(t))
{
StructDeclaration *sd = ((TypeStruct *)tb)->sym;
if (sd->ctor)
{
// Rewrite as S().ctor(exp)
Expression *e;
e = new StructLiteralExp(loc, sd, NULL);
e = new DotIdExp(loc, e, Id::ctor);
e = new CallExp(loc, e, exp);
e = e->semantic(sc);
if (needInterpret)
exp = e->ctfeInterpret();
else
exp = e->optimize(WANTvalue);
}
}
// Look for the case of statically initializing an array
// with a single member.
if (tb->ty == Tsarray &&
!tb->nextOf()->equals(ti->toBasetype()->nextOf()) &&
exp->implicitConvTo(tb->nextOf())
)
{
/* If the variable is not actually used in compile time, array creation is
* redundant. So delay it until invocation of toExpression() or toDt().
*/
t = tb->nextOf();
}
//.........这里部分代码省略.........
示例13: printf
//.........这里部分代码省略.........
else if (ident == Id::isFinalClass)
{
ISTYPE(t->toBasetype()->ty == Tclass && ((TypeClass *)t->toBasetype())->sym->storage_class & STCfinal)
}
else if (ident == Id::isAbstractFunction)
{
ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isAbstract())
}
else if (ident == Id::isVirtualFunction)
{
ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isVirtual())
}
else if (ident == Id::isFinalFunction)
{
ISDSYMBOL((f = s->isFuncDeclaration()) != NULL && f->isFinal())
}
else if (ident == Id::hasMember ||
ident == Id::getMember ||
ident == Id::getVirtualFunctions)
{
if (dim != 2)
goto Ldimerror;
Object *o = (Object *)args->data[0];
Expression *e = isExpression((Object *)args->data[1]);
if (!e)
{ // error("expression expected as second argument of __traits %s", ident->toChars());
goto Lfalse;
}
e = e->optimize(WANTvalue | WANTinterpret);
if (e->op != TOKstring)
{ // error("string expected as second argument of __traits %s instead of %s", ident->toChars(), e->toChars());
goto Lfalse;
}
StringExp *se = (StringExp *)e;
se = se->toUTF8(sc);
if (se->sz != 1)
{ // error("string must be chars");
goto Lfalse;
}
Identifier *id = Lexer::idPool((char *)se->string);
Type *t = isType(o);
e = isExpression(o);
Dsymbol *s = isDsymbol(o);
if (t)
e = new TypeDotIdExp(loc, t, id);
else if (e)
e = new DotIdExp(loc, e, id);
else if (s)
{ e = new DsymbolExp(loc, s);
e = new DotIdExp(loc, e, id);
}
else
{ // error("invalid first argument");
goto Lfalse;
}
if (ident == Id::hasMember)
{ /* Take any errors as meaning it wasn't found
*/
unsigned errors = global.errors;
global.gag++;
e = e->semantic(sc);
global.gag--;
if (errors != global.errors)
{ if (global.gag == 0)
示例14: resolveProperties
void PragmaDeclaration::semantic(Scope *sc)
{ // Should be merged with PragmaStatement
#if IN_LLVM
Pragma llvm_internal = LLVMnone;
std::string arg1str;
#endif
//printf("\tPragmaDeclaration::semantic '%s'\n",toChars());
if (ident == Id::msg)
{
if (args)
{
for (size_t i = 0; i < args->dim; i++)
{
Expression *e = (*args)[i];
sc = sc->startCTFE();
e = e->semantic(sc);
e = resolveProperties(sc, e);
sc = sc->endCTFE();
// pragma(msg) is allowed to contain types as well as expressions
e = ctfeInterpretForPragmaMsg(e);
if (e->op == TOKerror)
{ errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
return;
}
StringExp *se = e->toString();
if (se)
{
se = se->toUTF8(sc);
fprintf(stderr, "%.*s", (int)se->len, (char *)se->string);
}
else
fprintf(stderr, "%s", e->toChars());
}
fprintf(stderr, "\n");
}
goto Lnodecl;
}
else if (ident == Id::lib)
{
if (!args || args->dim != 1)
error("string expected for library name");
else
{
Expression *e = (*args)[0];
sc = sc->startCTFE();
e = e->semantic(sc);
e = resolveProperties(sc, e);
sc = sc->endCTFE();
e = e->ctfeInterpret();
(*args)[0] = e;
if (e->op == TOKerror)
goto Lnodecl;
StringExp *se = e->toString();
if (!se)
error("string expected for library name, not '%s'", e->toChars());
else
{
char *name = (char *)mem.malloc(se->len + 1);
memcpy(name, se->string, se->len);
name[se->len] = 0;
if (global.params.verbose)
fprintf(global.stdmsg, "library %s\n", name);
if (global.params.moduleDeps && !global.params.moduleDepsFile)
{
OutBuffer *ob = global.params.moduleDeps;
Module *imod = sc->instantiatingModule();
ob->writestring("depsLib ");
ob->writestring(imod->toPrettyChars());
ob->writestring(" (");
escapePath(ob, imod->srcfile->toChars());
ob->writestring(") : ");
ob->writestring((char *) name);
ob->writenl();
}
mem.free(name);
}
}
goto Lnodecl;
}
else if (ident == Id::startaddress)
{
if (!args || args->dim != 1)
error("function name expected for start address");
else
{
/* Bugzilla 11980:
* resolveProperties and ctfeInterpret call are not necessary.
*/
Expression *e = (*args)[0];
sc = sc->startCTFE();
e = e->semantic(sc);
sc = sc->endCTFE();
//.........这里部分代码省略.........
示例15: printf
//.........这里部分代码省略.........
{
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];
Dsymbol *s = getDsymbol(o);
if (!s)
{
if (!isError(o))
e->error("argument %s has no protection", o->toChars());
goto Lfalse;
}
if (s->scope)
s->semantic(s->scope);
PROT protection = s->prot();
const char *protName = Pprotectionnames[protection];
assert(protName);
StringExp *se = new StringExp(e->loc, (char *) protName);
return se->semantic(sc);