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]; e = e->semantic(sc); if (e->op != TOKerror && e->op != TOKtype) e = e->ctfeInterpret(); StringExp *se = e->toString(); if (se) { fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); } else fprintf(stdmsg, "%s", e->toChars()); } fprintf(stdmsg, "\n"); } goto Lnodecl; } else if (ident == Id::lib) { if (!args || args->dim != 1) error("string expected for library name"); else { Expression *e = (*args)[0]; e = e->semantic(sc); 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 if (global.params.verbose) { char *name = (char *)mem.malloc(se->len + 1); memcpy(name, se->string, se->len); name[se->len] = 0; printf("library %s\n", name); mem.free(name); } } goto Lnodecl; } #if IN_GCC else if (ident == Id::GNU_asm) { if (! args || args->dim != 2) error("identifier and string expected for asm name"); else { Expression *e; Declaration *d = NULL; StringExp *s = NULL; e = (*args)[0]; e = e->semantic(sc); if (e->op == TOKvar) { d = ((VarExp *)e)->var; if (! d->isFuncDeclaration() && ! d->isVarDeclaration()) d = NULL; } if (!d) error("first argument of GNU_asm must be a function or variable declaration"); e = (*args)[1]; e = e->semantic(sc); e = e->optimize(WANTvalue); e = e->toString(); if (e && ((StringExp *)e)->sz == 1) s = ((StringExp *)e); else error("second argument of GNU_asm must be a character string"); if (d && s) d->c_ident = Lexer::idPool((char*) s->string); } goto Lnodecl; } #endif #if DMDV2 else if (ident == Id::startaddress) { if (!args || args->dim != 1) error("function name expected for start address"); else { Expression *e = (*args)[0]; e = e->semantic(sc); e = e->ctfeInterpret(); (*args)[0] = e; Dsymbol *sa = getDsymbol(e); if (!sa || !sa->isFuncDeclaration()) error("function name expected for start address, not '%s'", e->toChars()); } goto Lnodecl; } #endif #if TARGET_NET else if (ident == Lexer::idPool("assembly")) { } #endif // TARGET_NET #if IN_LLVM else if ((llvm_internal = DtoGetPragma(sc, this, arg1str)) != LLVMnone) { // nothing to do anymore } #endif else if (global.params.ignoreUnsupportedPragmas) { if (global.params.verbose) { /* Print unrecognized pragmas */ printf("pragma %s", ident->toChars()); if (args) { for (size_t i = 0; i < args->dim; i++) { #if IN_LLVM // ignore errors in ignored pragmas. global.gag++; unsigned errors_save = global.errors; #endif Expression *e = (*args)[i]; e = e->semantic(sc); e = e->ctfeInterpret(); if (i == 0) printf(" ("); else printf(","); printf("%s", e->toChars()); #if IN_LLVM // restore error state. global.gag--; global.errors = errors_save; #endif } if (args->dim) printf(")"); } printf("\n"); } goto Lnodecl; } else error("unrecognized pragma(%s)", ident->toChars()); Ldecl: if (decl) { for (size_t i = 0; i < decl->dim; i++) { Dsymbol *s = (*decl)[i]; s->semantic(sc); #if IN_LLVM DtoCheckPragma(this, s, llvm_internal, arg1str); #endif } } return; Lnodecl: if (decl) { error("pragma is missing closing ';'"); goto Ldecl; // do them anyway, to avoid segfaults. } }
void PragmaDeclaration::semantic(Scope *sc) { // Should be merged with PragmaStatement #if IN_LLVM int llvm_internal = 0; 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 = (Expression *)args->data[i]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); if (e->op == TOKstring) { StringExp *se = (StringExp *)e; fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); } else fprintf(stdmsg, "%s", e->toChars()); } fprintf(stdmsg, "\n"); } goto Lnodecl; } else if (ident == Id::lib) { if (!args || args->dim != 1) error("string expected for library name"); else { Expression *e = (Expression *)args->data[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); args->data[0] = (void *)e; if (e->op != TOKstring) error("string expected for library name, not '%s'", e->toChars()); else if (global.params.verbose) { StringExp *se = (StringExp *)e; char *name = (char *)mem.malloc(se->len + 1); memcpy(name, se->string, se->len); name[se->len] = 0; printf("library %s\n", name); mem.free(name); } } goto Lnodecl; } #if IN_GCC else if (ident == Id::GNU_asm) { if (! args || args->dim != 2) error("identifier and string expected for asm name"); else { Expression *e; Declaration *d = NULL; StringExp *s = NULL; e = (Expression *)args->data[0]; e = e->semantic(sc); if (e->op == TOKvar) { d = ((VarExp *)e)->var; if (! d->isFuncDeclaration() && ! d->isVarDeclaration()) d = NULL; } if (!d) error("first argument of GNU_asm must be a function or variable declaration"); e = (Expression *)args->data[1]; e = e->semantic(sc); e = e->optimize(WANTvalue); if (e->op == TOKstring && ((StringExp *)e)->sz == 1) s = ((StringExp *)e); else error("second argument of GNU_asm must be a char string"); if (d && s) d->c_ident = Lexer::idPool((char*) s->string); } goto Lnodecl; } #endif #if DMDV2 else if (ident == Id::startaddress) { if (!args || args->dim != 1) error("function name expected for start address"); else { Expression *e = (Expression *)args->data[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); args->data[0] = (void *)e; Dsymbol *sa = getDsymbol(e); if (!sa || !sa->isFuncDeclaration()) error("function name expected for start address, not '%s'", e->toChars()); } goto Lnodecl; } #endif #if TARGET_NET else if (ident == Lexer::idPool("assembly")) { } #endif // TARGET_NET // LDC #if IN_LLVM // pragma(intrinsic, "string") { funcdecl(s) } else if (ident == Id::intrinsic) { Expression* expr = (Expression *)args->data[0]; expr = expr->semantic(sc); if (!args || args->dim != 1 || !parseStringExp(expr, arg1str)) { error("requires exactly 1 string literal parameter"); fatal(); } llvm_internal = LLVMintrinsic; } // pragma(notypeinfo) { typedecl(s) } else if (ident == Id::no_typeinfo) { if (args && args->dim > 0) { error("takes no parameters"); fatal(); } llvm_internal = LLVMno_typeinfo; } // pragma(nomoduleinfo) ; else if (ident == Id::no_moduleinfo) { if (args && args->dim > 0) { error("takes no parameters"); fatal(); } llvm_internal = LLVMno_moduleinfo; } // pragma(alloca) { funcdecl(s) } else if (ident == Id::Alloca) { if (args && args->dim > 0) { error("takes no parameters"); fatal(); } llvm_internal = LLVMalloca; } // pragma(va_start) { templdecl(s) } else if (ident == Id::vastart) { if (args && args->dim > 0) { error("takes no parameters"); fatal(); } llvm_internal = LLVMva_start; } // pragma(va_copy) { funcdecl(s) } else if (ident == Id::vacopy) { if (args && args->dim > 0) { error("takes no parameters"); fatal(); } llvm_internal = LLVMva_copy; } // pragma(va_end) { funcdecl(s) } else if (ident == Id::vaend) { if (args && args->dim > 0) { error("takes no parameters"); fatal(); } llvm_internal = LLVMva_end; } // pragma(va_arg) { templdecl(s) } else if (ident == Id::vaarg) { if (args && args->dim > 0) { error("takes no parameters"); fatal(); } llvm_internal = LLVMva_arg; } // pragma(fence) { templdecl(s) } else if (ident == Id::fence) { if (args && args->dim > 0) { error("takes no parameters"); fatal(); } llvm_internal = LLVMfence; } // pragma(atomic_load) { templdecl(s) } else if (ident == Id::atomic_load) { if (args && args->dim > 0) { error("takes no parameters"); fatal(); } llvm_internal = LLVMatomic_load; } // pragma(atomic_store) { templdecl(s) } else if (ident == Id::atomic_store) { if (args && args->dim > 0) { error("takes no parameters"); fatal(); } llvm_internal = LLVMatomic_store; } // pragma(atomic_cmp_xchg) { templdecl(s) } else if (ident == Id::atomic_cmp_xchg) { if (args && args->dim > 0) { error("takes no parameters"); fatal(); } llvm_internal = LLVMatomic_cmp_xchg; } // pragma(atomic_rmw, "string") { templdecl(s) } else if (ident == Id::atomic_rmw) { Expression* expr = (Expression *)args->data[0]; expr = expr->semantic(sc); if (!args || args->dim != 1 || !parseStringExp(expr, arg1str)) { error("requires exactly 1 string literal parameter"); fatal(); } llvm_internal = LLVMatomic_rmw; } // pragma(ldc, "string") { templdecl(s) } else if (ident == Id::ldc) { Expression* expr = (Expression *)args->data[0]; expr = expr->semantic(sc); if (!args || args->dim != 1 || !parseStringExp(expr, arg1str)) { error("requires exactly 1 string literal parameter"); fatal(); } else if (arg1str == "verbose") { sc->module->llvmForceLogging = true; } else { error("command '%s' invalid", expr->toChars()); fatal(); } } // pragma(llvm_inline_asm) { templdecl(s) } else if (ident == Id::llvm_inline_asm) { if (args && args->dim > 0) { error("takes no parameters"); fatal(); } llvm_internal = LLVMinline_asm; } #endif // LDC else if (ignoreUnsupportedPragmas) { if (global.params.verbose) { /* Print unrecognized pragmas */ printf("pragma %s", ident->toChars()); if (args) { for (size_t i = 0; i < args->dim; i++) { // ignore errors in ignored pragmas. global.gag++; unsigned errors_save = global.errors; Expression *e = (Expression *)args->data[i]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); if (i == 0) printf(" ("); else printf(","); printf("%s", e->toChars()); // restore error state. global.gag--; global.errors = errors_save; } if (args->dim) printf(")"); } printf("\n"); } } else error("unrecognized pragma(%s)", ident->toChars()); if (decl) { for (unsigned i = 0; i < decl->dim; i++) { Dsymbol *s = (Dsymbol *)decl->data[i]; s->semantic(sc); // LDC #if IN_LLVM if (llvm_internal) { if (s->llvmInternal) { error("multiple LDC specific pragmas not allowed not affect the same declaration ('%s' at '%s')", s->toChars(), s->loc.toChars()); fatal(); } switch(llvm_internal) { case LLVMintrinsic: if (FuncDeclaration* fd = s->isFuncDeclaration()) { fd->llvmInternal = llvm_internal; fd->intrinsicName = arg1str; fd->linkage = LINKintrinsic; ((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 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(); } else if (td->overnext || td->overroot) { error("the '%s' pragma template must not be overloaded", ident->toChars()); fatal(); } td->llvmInternal = llvm_internal; } else { error("the '%s' pragma is only allowed on template declarations", ident->toChars()); fatal(); } break; case LLVMva_copy: case LLVMva_end: case LLVMfence: if (FuncDeclaration* fd = s->isFuncDeclaration()) { fd->llvmInternal = llvm_internal; } else { error("the '%s' pragma is only allowed on function declarations", ident->toChars()); fatal(); } break; case LLVMno_typeinfo: s->llvmInternal = llvm_internal; break; case LLVMalloca: if (FuncDeclaration* fd = s->isFuncDeclaration()) { fd->llvmInternal = llvm_internal; } else { error("the '%s' pragma must only be used on function declarations of type 'void* function(uint nbytes)'", ident->toChars()); fatal(); } break; case LLVMinline_asm: if (TemplateDeclaration* td = s->isTemplateDeclaration()) { if (td->parameters->dim > 1) { error("the '%s' pragma template must have exactly zero or one template parameters", ident->toChars()); fatal(); } else if (!td->onemember) { error("the '%s' pragma template must have exactly one member", ident->toChars()); fatal(); } td->llvmInternal = llvm_internal; } else { error("the '%s' pragma is only allowed on template declarations", ident->toChars()); fatal(); } break; default: warning("the LDC specific pragma '%s' is not yet implemented, ignoring", ident->toChars()); } } #endif // LDC } } return; Lnodecl: if (decl) error("pragma is missing closing ';'"); }
void PragmaDeclaration::semantic(Scope *sc) { // Should be merged with PragmaStatement //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); if (ident == Id::msg) { if (args) { for (size_t i = 0; i < args->dim; i++) { Expression *e = args->tdata()[i]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); StringExp *se = e->toString(); if (se) { fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); } else fprintf(stdmsg, "%s", e->toChars()); } fprintf(stdmsg, "\n"); } goto Lnodecl; } else if (ident == Id::lib) { if (!args || args->dim != 1) error("string expected for library name"); else { Expression *e = args->tdata()[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); args->tdata()[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 if (global.params.verbose) { char *name = (char *)mem.malloc(se->len + 1); memcpy(name, se->string, se->len); name[se->len] = 0; printf("library %s\n", name); mem.free(name); } } goto Lnodecl; } #if IN_GCC else if (ident == Id::GNU_asm) { if (! args || args->dim != 2) error("identifier and string expected for asm name"); else { Expression *e; Declaration *d = NULL; StringExp *s = NULL; e = args->tdata()[0]; e = e->semantic(sc); if (e->op == TOKvar) { d = ((VarExp *)e)->var; if (! d->isFuncDeclaration() && ! d->isVarDeclaration()) d = NULL; } if (!d) error("first argument of GNU_asm must be a function or variable declaration"); e = args->tdata()[1]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); e = e->toString(); if (e && ((StringExp *)e)->sz == 1) s = ((StringExp *)e); else error("second argument of GNU_asm must be a char string"); if (d && s) d->c_ident = Lexer::idPool((char*) s->string); } goto Lnodecl; } #endif #if DMDV2 else if (ident == Id::startaddress) { if (!args || args->dim != 1) error("function name expected for start address"); else { Expression *e = args->tdata()[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); args->tdata()[0] = e; Dsymbol *sa = getDsymbol(e); if (!sa || !sa->isFuncDeclaration()) error("function name expected for start address, not '%s'", e->toChars()); } goto Lnodecl; } #endif #if TARGET_NET else if (ident == Lexer::idPool("assembly")) { } #endif // TARGET_NET else if (global.params.ignoreUnsupportedPragmas) { if (global.params.verbose) { /* Print unrecognized pragmas */ printf("pragma %s", ident->toChars()); if (args) { for (size_t i = 0; i < args->dim; i++) { Expression *e = args->tdata()[i]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); if (i == 0) printf(" ("); else printf(","); printf("%s", e->toChars()); } if (args->dim) printf(")"); } printf("\n"); } goto Lnodecl; } else error("unrecognized pragma(%s)", ident->toChars()); if (decl) { for (unsigned i = 0; i < decl->dim; i++) { Dsymbol *s = decl->tdata()[i]; s->semantic(sc); } } return; Lnodecl: if (decl) error("pragma is missing closing ';'"); }
void PragmaDeclaration::semantic(Scope *sc) { // Should be merged with PragmaStatement Scope sc_save; //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); if (ident == Id::msg) { if (args) { for (size_t i = 0; i < args->dim; i++) { Expression *e = args->tdata()[i]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); StringExp *se = e->toString(); if (se) { fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string); } else fprintf(stdmsg, "%s", e->toChars()); } fprintf(stdmsg, "\n"); } goto Lnodecl; } else if (ident == Id::lib) { if (!args || args->dim != 1) error("string expected for library name"); else { Expression *e = args->tdata()[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); args->tdata()[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 if (global.params.verbose) { char *name = (char *)mem.malloc(se->len + 1); memcpy(name, se->string, se->len); name[se->len] = 0; printf("library %s\n", name); mem.free(name); } } goto Lnodecl; } #if IN_GCC else if (ident == Id::GNU_asm) { if (! args || args->dim != 2) error("identifier and string expected for asm name"); else { Expression *e; Declaration *d = NULL; StringExp *s = NULL; e = (Expression *)args->data[0]; e = e->semantic(sc); if (e->op == TOKvar) { d = ((VarExp *)e)->var; if (! d->isFuncDeclaration() && ! d->isVarDeclaration()) d = NULL; } if (!d) error("first argument of GNU_asm must be a function or variable declaration"); e = args->tdata()[1]; e = e->semantic(sc); e = e->optimize(WANTvalue); e = e->toString(); if (e && ((StringExp *)e)->sz == 1) s = ((StringExp *)e); else error("second argument of GNU_asm must be a character string"); if (d && s) d->c_ident = Lexer::idPool((char*) s->string); } goto Lnodecl; } else if (ident == Id::GNU_attribute || ident == Id::_GNU_attribute) { if (!global.params.useDeprecated && ident == Id::_GNU_attribute) error("pragma(GNU_attribute) is deprecated, use pragma(attribute) instead"); sc_save = *sc; // An empty list is allowed. if (args && args->dim) { Expressions * a; if (sc->attributes) a = (Expressions *) sc->attributes->copy(); else a = new Expressions; sc->attributes = a; for (unsigned i = 0; i < args->dim; i++) { Expression * e = args->tdata()[i]; //e = e->semantic(sc); if (e->op == TOKidentifier) ; // ok else if (e->op == TOKcall) { CallExp * c = (CallExp *) e; if (c->e1->op != TOKidentifier) error("identifier or call expression expected for attribute"); if (c->arguments) for (int unsigned ai = 0; ai < c->arguments->dim; ai++) { Expression * ea = c->arguments->tdata()[ai]; ea = ea->semantic(sc); ea = ea->optimize(WANTvalue | WANTinterpret); c->arguments->tdata()[ai] = ea; } } else { error("identifier or call expression expected for attribute"); continue; } a->push(e); } } } else if (ident == Id::GNU_set_attribute || ident == Id::_GNU_set_attribute) { if (!global.params.useDeprecated && ident == Id::_GNU_set_attribute) error("pragma(GNU_set_attribute) is deprecated, use pragma(set_attribute) instead"); if (!args || args->dim < 1) error("declaration expected for setting attributes"); else { Expressions ** p_attributes = NULL; // list of existing attributes { Expression * e = args->tdata()[0]; e = e->semantic(sc); if (e->op == TOKvar) { Declaration * d = ((VarExp *)e)->var; if (d->isFuncDeclaration() || d->isVarDeclaration()) p_attributes = & d->attributes; } else if (e->op == TOKtype) { Type * t = ((TypeExp *)e)->type; if (t->ty == Ttypedef) p_attributes = & ((TypeTypedef *) t)->sym->attributes; else if (t->ty == Tenum) p_attributes = & ((TypeEnum *) t)->sym->attributes; else if (t->ty == Tstruct) p_attributes = & ((TypeStruct *) t)->sym->attributes; else if (t->ty == Tclass) p_attributes = & ((TypeClass *) t)->sym->attributes; } if (p_attributes == NULL) error("first argument must be a function, variable, or type declaration"); } Expressions * new_attrs = new Expressions; for (unsigned i = 1; i < args->dim; i++) { Expression * e = args->tdata()[i]; //e = e->semantic(sc); if (e->op == TOKidentifier) ; // ok else if (e->op == TOKcall) { CallExp * c = (CallExp *) e; if (c->e1->op != TOKidentifier) error("identifier or call expression expected for attribute"); if (c->arguments) for (int unsigned ai = 0; ai < c->arguments->dim; ai++) { Expression * ea = c->arguments->tdata()[ai]; ea = ea->semantic(sc); ea = ea->optimize(WANTvalue | WANTinterpret); c->arguments->tdata()[ai] = ea; } } else { error("identifier or call expression expected for attribute"); continue; } new_attrs->push(e); } if (p_attributes) { if (*p_attributes) { *p_attributes = (Expressions *) (*p_attributes)->copy(); (*p_attributes)->append(new_attrs); } else *p_attributes = new_attrs; } } goto Lnodecl; } #endif #if DMDV2 else if (ident == Id::startaddress) { if (!args || args->dim != 1) error("function name expected for start address"); else { Expression *e = (Expression *)args->data[0]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); args->data[0] = (void *)e; Dsymbol *sa = getDsymbol(e); if (!sa || !sa->isFuncDeclaration()) error("function name expected for start address, not '%s'", e->toChars()); } goto Lnodecl; } #endif #if TARGET_NET else if (ident == Lexer::idPool("assembly")) { } #endif // TARGET_NET else if (global.params.ignoreUnsupportedPragmas) { if (global.params.verbose) { /* Print unrecognized pragmas */ printf("pragma %s", ident->toChars()); if (args) { for (size_t i = 0; i < args->dim; i++) { Expression *e = (Expression *)args->data[i]; e = e->semantic(sc); e = e->optimize(WANTvalue | WANTinterpret); if (i == 0) printf(" ("); else printf(","); printf("%s", e->toChars()); } if (args->dim) printf(")"); } printf("\n"); } goto Lnodecl; } else error("unrecognized pragma(%s)", ident->toChars()); if (decl) { for (unsigned i = 0; i < decl->dim; i++) { Dsymbol *s = decl->tdata()[i]; s->semantic(sc); } } #if IN_GCC if (decl) if (ident == Id::GNU_attribute || ident == Id::_GNU_attribute) *sc = sc_save; #endif return; Lnodecl: if (decl) error("pragma is missing closing ';'"); }
void PragmaDeclaration::semantic(Scope *sc) { // Should be merged with PragmaStatement //printf("\tPragmaDeclaration::semantic '%s'\n",toChars()); if (ident == Id::msg) { if (args) { for (size_t i = 0; i < args->dim; i++) { Expression *e = (Expression *)args->data[i]; e = e->semantic(sc); if (e->op == TOKstring) { StringExp *se = (StringExp *)e; fprintf(stdmsg, "%.*s", se->len, se->string); } else error("string expected for message, not '%s'", e->toChars()); } fprintf(stdmsg, "\n"); } goto Lnodecl; } else if (ident == Id::lib) { if (!args || args->dim != 1) error("string expected for library name"); else { Expression *e = (Expression *)args->data[0]; e = e->semantic(sc); args->data[0] = (void *)e; if (e->op != TOKstring) error("string expected for library name, not '%s'", e->toChars()); } goto Lnodecl; } #if IN_GCC else if (ident == Id::GNU_asm) { if (! args || args->dim != 2) error("identifier and string expected for asm name"); else { Expression *e; Declaration *d = NULL; StringExp *s = NULL; e = (Expression *)args->data[0]; e = e->semantic(sc); if (e->op == TOKvar) { d = ((VarExp *)e)->var; if (! d->isFuncDeclaration() && ! d->isVarDeclaration()) d = NULL; } if (!d) error("first argument of GNU_asm must be a function or variable declaration"); e = (Expression *)args->data[1]; e = e->semantic(sc); e = e->optimize(WANTvalue); if (e->op == TOKstring && ((StringExp *)e)->sz == 1) s = ((StringExp *)e); else error("second argument of GNU_asm must be a char string"); if (d && s) d->c_ident = Lexer::idPool((char*) s->string); } goto Lnodecl; } #endif else error("unrecognized pragma(%s)", ident->toChars()); if (decl) { for (unsigned i = 0; i < decl->dim; i++) { Dsymbol *s = (Dsymbol *)decl->data[i]; s->semantic(sc); } } return; Lnodecl: if (decl) error("pragma is missing closing ';'"); }