mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
Refactoring: moved ldc specific code from dmd/attrib.c and dmd2/attrib.c into gen/pragma.cpp
This commit is contained in:
551
dmd/attrib.c
551
dmd/attrib.c
@@ -1,6 +1,6 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2011 by Digital Mars
|
||||
// Copyright (c) 1999-2011 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
@@ -29,16 +29,8 @@
|
||||
#if TARGET_NET
|
||||
#include "frontend.net/pragma.h"
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
#include "../gen/enums.h"
|
||||
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
||||
static llvm::cl::opt<bool> ignoreUnsupportedPragmas("ignore",
|
||||
llvm::cl::desc("Ignore unsupported pragmas"),
|
||||
llvm::cl::ZeroOrMore);
|
||||
|
||||
#include "../gen/pragma.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -51,13 +43,13 @@ void obj_startaddress(Symbol *s);
|
||||
|
||||
/********************************* AttribDeclaration ****************************/
|
||||
|
||||
AttribDeclaration::AttribDeclaration(Dsymbols *decl)
|
||||
AttribDeclaration::AttribDeclaration(Dsymbols *decl)
|
||||
: Dsymbol()
|
||||
{
|
||||
this->decl = decl;
|
||||
}
|
||||
|
||||
Dsymbols *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd)
|
||||
Dsymbols *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd)
|
||||
{
|
||||
return decl;
|
||||
}
|
||||
@@ -65,13 +57,13 @@ Dsymbols *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd)
|
||||
int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
|
||||
{
|
||||
int m = 0;
|
||||
Dsymbols *d = include(sc, sd);
|
||||
Dsymbols *d = include(sc, sd);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
//printf("\taddMember %s to %s\n", s->toChars(), sd->toChars());
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
//printf("\taddMember %s to %s\n", s->toChars(), sd->toChars());
|
||||
m |= s->addMember(sc, sd, m | memnum);
|
||||
}
|
||||
}
|
||||
@@ -101,7 +93,7 @@ void AttribDeclaration::setScopeNewSc(Scope *sc,
|
||||
newsc->structalign = structalign;
|
||||
}
|
||||
for (unsigned i = 0; i < decl->dim; i++)
|
||||
{ Dsymbol *s = decl->tdata()[i];
|
||||
{ Dsymbol *s = decl->tdata()[i];
|
||||
|
||||
s->setScope(newsc); // yes, the only difference from semanticNewSc()
|
||||
}
|
||||
@@ -136,7 +128,7 @@ void AttribDeclaration::semanticNewSc(Scope *sc,
|
||||
newsc->structalign = structalign;
|
||||
}
|
||||
for (unsigned i = 0; i < decl->dim; i++)
|
||||
{ Dsymbol *s = decl->tdata()[i];
|
||||
{ Dsymbol *s = decl->tdata()[i];
|
||||
|
||||
s->semantic(newsc);
|
||||
}
|
||||
@@ -150,14 +142,14 @@ void AttribDeclaration::semanticNewSc(Scope *sc,
|
||||
|
||||
void AttribDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
Dsymbols *d = include(sc, NULL);
|
||||
Dsymbols *d = include(sc, NULL);
|
||||
|
||||
//printf("\tAttribDeclaration::semantic '%s', d = %p\n",toChars(), d);
|
||||
if (d)
|
||||
{
|
||||
for (size_t i = 0; i < d->dim; i++)
|
||||
for (size_t i = 0; i < d->dim; i++)
|
||||
{
|
||||
Dsymbol *s = d->tdata()[i];
|
||||
Dsymbol *s = d->tdata()[i];
|
||||
|
||||
s->semantic(sc);
|
||||
}
|
||||
@@ -166,12 +158,12 @@ void AttribDeclaration::semantic(Scope *sc)
|
||||
|
||||
void AttribDeclaration::semantic2(Scope *sc)
|
||||
{
|
||||
Dsymbols *d = include(sc, NULL);
|
||||
Dsymbols *d = include(sc, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (size_t i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
for (size_t i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
s->semantic2(sc);
|
||||
}
|
||||
}
|
||||
@@ -179,12 +171,12 @@ void AttribDeclaration::semantic2(Scope *sc)
|
||||
|
||||
void AttribDeclaration::semantic3(Scope *sc)
|
||||
{
|
||||
Dsymbols *d = include(sc, NULL);
|
||||
Dsymbols *d = include(sc, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (size_t i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
for (size_t i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
s->semantic3(sc);
|
||||
}
|
||||
}
|
||||
@@ -192,12 +184,12 @@ void AttribDeclaration::semantic3(Scope *sc)
|
||||
|
||||
void AttribDeclaration::inlineScan()
|
||||
{
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
//printf("AttribDeclaration::inlineScan %s\n", s->toChars());
|
||||
s->inlineScan();
|
||||
}
|
||||
@@ -206,15 +198,15 @@ void AttribDeclaration::inlineScan()
|
||||
|
||||
void AttribDeclaration::addComment(unsigned char *comment)
|
||||
{
|
||||
//printf("AttribDeclaration::addComment %s\n", comment);
|
||||
//printf("AttribDeclaration::addComment %s\n", comment);
|
||||
if (comment)
|
||||
{
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
//printf("AttribDeclaration::addComment %s\n", s->toChars());
|
||||
s->addComment(comment);
|
||||
}
|
||||
@@ -234,12 +226,12 @@ void AttribDeclaration::emitComment(Scope *sc)
|
||||
* Hence, Ddoc omits attributes from template members.
|
||||
*/
|
||||
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
//printf("AttribDeclaration::emitComment %s\n", s->toChars());
|
||||
s->emitComment(sc);
|
||||
}
|
||||
@@ -250,12 +242,12 @@ void AttribDeclaration::emitComment(Scope *sc)
|
||||
|
||||
void AttribDeclaration::toObjFile(int multiobj)
|
||||
{
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
s->toObjFile(multiobj);
|
||||
}
|
||||
}
|
||||
@@ -265,12 +257,12 @@ int AttribDeclaration::cvMember(unsigned char *p)
|
||||
{
|
||||
int nwritten = 0;
|
||||
int n;
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
n = s->cvMember(p);
|
||||
if (p)
|
||||
p += n;
|
||||
@@ -283,13 +275,13 @@ int AttribDeclaration::cvMember(unsigned char *p)
|
||||
|
||||
int AttribDeclaration::hasPointers()
|
||||
{
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (size_t i = 0; i < d->dim; i++)
|
||||
{
|
||||
Dsymbol *s = d->tdata()[i];
|
||||
Dsymbol *s = d->tdata()[i];
|
||||
if (s->hasPointers())
|
||||
return 1;
|
||||
}
|
||||
@@ -297,22 +289,22 @@ int AttribDeclaration::hasPointers()
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool AttribDeclaration::hasStaticCtorOrDtor()
|
||||
{
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (size_t i = 0; i < d->dim; i++)
|
||||
{
|
||||
Dsymbol *s = (*d)[i];
|
||||
if (s->hasStaticCtorOrDtor())
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool AttribDeclaration::hasStaticCtorOrDtor()
|
||||
{
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (size_t i = 0; i < d->dim; i++)
|
||||
{
|
||||
Dsymbol *s = (*d)[i];
|
||||
if (s->hasStaticCtorOrDtor())
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const char *AttribDeclaration::kind()
|
||||
{
|
||||
return "attribute";
|
||||
@@ -320,19 +312,19 @@ const char *AttribDeclaration::kind()
|
||||
|
||||
int AttribDeclaration::oneMember(Dsymbol **ps)
|
||||
{
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
|
||||
return Dsymbol::oneMembers(d, ps);
|
||||
}
|
||||
|
||||
void AttribDeclaration::checkCtorConstInit()
|
||||
{
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
s->checkCtorConstInit();
|
||||
}
|
||||
}
|
||||
@@ -343,12 +335,12 @@ void AttribDeclaration::checkCtorConstInit()
|
||||
|
||||
void AttribDeclaration::addLocalClass(ClassDeclarations *aclasses)
|
||||
{
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
Dsymbols *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
s->addLocalClass(aclasses);
|
||||
}
|
||||
}
|
||||
@@ -362,7 +354,7 @@ void AttribDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
if (decl->dim == 0)
|
||||
buf->writestring("{}");
|
||||
else if (decl->dim == 1)
|
||||
(decl->tdata()[0])->toCBuffer(buf, hgs);
|
||||
(decl->tdata()[0])->toCBuffer(buf, hgs);
|
||||
else
|
||||
{
|
||||
buf->writenl();
|
||||
@@ -370,7 +362,7 @@ void AttribDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
buf->writenl();
|
||||
for (unsigned i = 0; i < decl->dim; i++)
|
||||
{
|
||||
Dsymbol *s = decl->tdata()[i];
|
||||
Dsymbol *s = decl->tdata()[i];
|
||||
|
||||
buf->writestring(" ");
|
||||
s->toCBuffer(buf, hgs);
|
||||
@@ -385,7 +377,7 @@ void AttribDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
|
||||
/************************* StorageClassDeclaration ****************************/
|
||||
|
||||
StorageClassDeclaration::StorageClassDeclaration(StorageClass stc, Dsymbols *decl)
|
||||
StorageClassDeclaration::StorageClassDeclaration(StorageClass stc, Dsymbols *decl)
|
||||
: AttribDeclaration(decl)
|
||||
{
|
||||
this->stc = stc;
|
||||
@@ -527,7 +519,7 @@ void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
|
||||
/********************************* LinkDeclaration ****************************/
|
||||
|
||||
LinkDeclaration::LinkDeclaration(enum LINK p, Dsymbols *decl)
|
||||
LinkDeclaration::LinkDeclaration(enum LINK p, Dsymbols *decl)
|
||||
: AttribDeclaration(decl)
|
||||
{
|
||||
//printf("LinkDeclaration(linkage = %d, decl = %p)\n", p, decl);
|
||||
@@ -570,7 +562,7 @@ void LinkDeclaration::semantic3(Scope *sc)
|
||||
sc->linkage = linkage;
|
||||
for (unsigned i = 0; i < decl->dim; i++)
|
||||
{
|
||||
Dsymbol *s = decl->tdata()[i];
|
||||
Dsymbol *s = decl->tdata()[i];
|
||||
|
||||
s->semantic3(sc);
|
||||
}
|
||||
@@ -613,7 +605,7 @@ char *LinkDeclaration::toChars()
|
||||
|
||||
/********************************* ProtDeclaration ****************************/
|
||||
|
||||
ProtDeclaration::ProtDeclaration(enum PROT p, Dsymbols *decl)
|
||||
ProtDeclaration::ProtDeclaration(enum PROT p, Dsymbols *decl)
|
||||
: AttribDeclaration(decl)
|
||||
{
|
||||
protection = p;
|
||||
@@ -650,9 +642,9 @@ void ProtDeclaration::importAll(Scope *sc)
|
||||
newsc->explicitProtection = 1;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < decl->dim; i++)
|
||||
for (size_t i = 0; i < decl->dim; i++)
|
||||
{
|
||||
Dsymbol *s = (*decl)[i];
|
||||
Dsymbol *s = (*decl)[i];
|
||||
s->importAll(newsc);
|
||||
}
|
||||
|
||||
@@ -695,7 +687,7 @@ void ProtDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
|
||||
/********************************* AlignDeclaration ****************************/
|
||||
|
||||
AlignDeclaration::AlignDeclaration(Loc loc, unsigned sa, Dsymbols *decl)
|
||||
AlignDeclaration::AlignDeclaration(Loc loc, unsigned sa, Dsymbols *decl)
|
||||
: AttribDeclaration(decl)
|
||||
{
|
||||
this->loc = loc;
|
||||
@@ -739,7 +731,7 @@ void AlignDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
|
||||
/********************************* AnonDeclaration ****************************/
|
||||
|
||||
AnonDeclaration::AnonDeclaration(Loc loc, int isunion, Dsymbols *decl)
|
||||
AnonDeclaration::AnonDeclaration(Loc loc, int isunion, Dsymbols *decl)
|
||||
: AttribDeclaration(decl)
|
||||
{
|
||||
this->loc = loc;
|
||||
@@ -760,12 +752,12 @@ void AnonDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
//printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this);
|
||||
|
||||
if (sem == 1)
|
||||
{ //printf("already completed\n");
|
||||
scope = NULL;
|
||||
return; // semantic() already completed
|
||||
}
|
||||
|
||||
if (sem == 1)
|
||||
{ //printf("already completed\n");
|
||||
scope = NULL;
|
||||
return; // semantic() already completed
|
||||
}
|
||||
|
||||
Scope *scx = NULL;
|
||||
if (scope)
|
||||
{ sc = scope;
|
||||
@@ -813,7 +805,7 @@ void AnonDeclaration::semantic(Scope *sc)
|
||||
|
||||
for (unsigned i = 0; i < decl->dim; i++)
|
||||
{
|
||||
Dsymbol *s = decl->tdata()[i];
|
||||
Dsymbol *s = decl->tdata()[i];
|
||||
|
||||
s->semantic(sc);
|
||||
if (isunion)
|
||||
@@ -906,7 +898,7 @@ void AnonDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
for (unsigned i = 0; i < decl->dim; i++)
|
||||
{
|
||||
Dsymbol *s = decl->tdata()[i];
|
||||
Dsymbol *s = decl->tdata()[i];
|
||||
|
||||
//buf->writestring(" ");
|
||||
s->toCBuffer(buf, hgs);
|
||||
@@ -936,7 +928,7 @@ static bool parseStringExp(Expression* e, std::string& res)
|
||||
return false;
|
||||
}
|
||||
|
||||
PragmaDeclaration::PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Dsymbols *decl)
|
||||
PragmaDeclaration::PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Dsymbols *decl)
|
||||
: AttribDeclaration(decl)
|
||||
{
|
||||
this->loc = loc;
|
||||
@@ -966,16 +958,16 @@ void PragmaDeclaration::setScope(Scope *sc)
|
||||
}
|
||||
else
|
||||
{
|
||||
Expression *e = args->tdata()[0];
|
||||
Expression *e = args->tdata()[0];
|
||||
e = e->semantic(sc);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
args->tdata()[0] = e;
|
||||
StringExp* se = e->toString();
|
||||
if (!se)
|
||||
args->tdata()[0] = e;
|
||||
StringExp* se = e->toString();
|
||||
if (!se)
|
||||
{
|
||||
error("string expected, not '%s'", e->toChars());
|
||||
}
|
||||
PragmaScope* pragma = new PragmaScope(this, sc->parent, se);
|
||||
PragmaScope* pragma = new PragmaScope(this, sc->parent, se);
|
||||
|
||||
assert(sc);
|
||||
pragma->setScope(sc);
|
||||
@@ -993,9 +985,8 @@ void PragmaDeclaration::semantic(Scope *sc)
|
||||
{ // Should be merged with PragmaStatement
|
||||
|
||||
#if IN_LLVM
|
||||
int llvm_internal = 0;
|
||||
Pragma llvm_internal = LLVMnone;
|
||||
std::string arg1str;
|
||||
|
||||
#endif
|
||||
|
||||
//printf("\tPragmaDeclaration::semantic '%s'\n",toChars());
|
||||
@@ -1005,12 +996,12 @@ void PragmaDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
for (size_t i = 0; i < args->dim; i++)
|
||||
{
|
||||
Expression *e = args->tdata()[i];
|
||||
Expression *e = args->tdata()[i];
|
||||
|
||||
e = e->semantic(sc);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
StringExp *se = e->toString();
|
||||
if (se)
|
||||
StringExp *se = e->toString();
|
||||
if (se)
|
||||
{
|
||||
fprintf(stdmsg, "%.*s", (int)se->len, (char *)se->string);
|
||||
}
|
||||
@@ -1027,15 +1018,15 @@ void PragmaDeclaration::semantic(Scope *sc)
|
||||
error("string expected for library name");
|
||||
else
|
||||
{
|
||||
Expression *e = args->tdata()[0];
|
||||
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)
|
||||
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)
|
||||
{
|
||||
@@ -1070,11 +1061,11 @@ void PragmaDeclaration::semantic(Scope *sc)
|
||||
if (!d)
|
||||
error("first argument of GNU_asm must be a function or variable declaration");
|
||||
|
||||
e = args->tdata()[1];
|
||||
e = args->tdata()[1];
|
||||
e = e->semantic(sc);
|
||||
e = e->optimize(WANTvalue);
|
||||
e = e->toString();
|
||||
if (e && ((StringExp *)e)->sz == 1)
|
||||
e = e->toString();
|
||||
if (e && ((StringExp *)e)->sz == 1)
|
||||
s = ((StringExp *)e);
|
||||
else
|
||||
error("second argument of GNU_asm must be a char string");
|
||||
@@ -1108,193 +1099,13 @@ void PragmaDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
}
|
||||
#endif // TARGET_NET
|
||||
|
||||
// LDC
|
||||
#if IN_LLVM
|
||||
|
||||
// pragma(intrinsic, "string") { funcdecl(s) }
|
||||
else if (ident == Id::intrinsic)
|
||||
else if ((llvm_internal = DtoGetPragma(sc, this, arg1str)) != LLVMnone)
|
||||
{
|
||||
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;
|
||||
// nothing to do anymore
|
||||
}
|
||||
|
||||
// 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)
|
||||
#endif
|
||||
else if (global.params.ignoreUnsupportedPragmas)
|
||||
{
|
||||
if (global.params.verbose)
|
||||
{
|
||||
@@ -1335,146 +1146,14 @@ void PragmaDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
for (unsigned i = 0; i < decl->dim; i++)
|
||||
{
|
||||
Dsymbol *s = decl->tdata()[i];
|
||||
Dsymbol *s = decl->tdata()[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();
|
||||
DtoCheckPragma(this, s, llvm_internal, arg1str);
|
||||
#endif
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -1520,7 +1199,7 @@ void PragmaDeclaration::toObjFile(int multiobj)
|
||||
* so instead append the library name to the list to be passed
|
||||
* to the linker.
|
||||
*/
|
||||
global.params.libfiles->push(name);
|
||||
global.params.libfiles->push(name);
|
||||
#else
|
||||
error("pragma lib not supported");
|
||||
#endif
|
||||
@@ -1561,7 +1240,7 @@ void PragmaDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
|
||||
/********************************* ConditionalDeclaration ****************************/
|
||||
|
||||
ConditionalDeclaration::ConditionalDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl)
|
||||
ConditionalDeclaration::ConditionalDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl)
|
||||
: AttribDeclaration(decl)
|
||||
{
|
||||
//printf("ConditionalDeclaration::ConditionalDeclaration()\n");
|
||||
@@ -1586,7 +1265,7 @@ int ConditionalDeclaration::oneMember(Dsymbol **ps)
|
||||
//printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition->inc);
|
||||
if (condition->inc)
|
||||
{
|
||||
Dsymbols *d = condition->include(NULL, NULL) ? decl : elsedecl;
|
||||
Dsymbols *d = condition->include(NULL, NULL) ? decl : elsedecl;
|
||||
return Dsymbol::oneMembers(d, ps);
|
||||
}
|
||||
*ps = NULL;
|
||||
@@ -1605,9 +1284,9 @@ void ConditionalDeclaration::emitComment(Scope *sc)
|
||||
/* If generating doc comment, be careful because if we're inside
|
||||
* a template, then include(NULL, NULL) will fail.
|
||||
*/
|
||||
Dsymbols *d = decl ? decl : elsedecl;
|
||||
Dsymbols *d = decl ? decl : elsedecl;
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
{ Dsymbol *s = d->tdata()[i];
|
||||
s->emitComment(sc);
|
||||
}
|
||||
}
|
||||
@@ -1615,7 +1294,7 @@ void ConditionalDeclaration::emitComment(Scope *sc)
|
||||
|
||||
// Decide if 'then' or 'else' code should be included
|
||||
|
||||
Dsymbols *ConditionalDeclaration::include(Scope *sc, ScopeDsymbol *sd)
|
||||
Dsymbols *ConditionalDeclaration::include(Scope *sc, ScopeDsymbol *sd)
|
||||
{
|
||||
//printf("ConditionalDeclaration::include()\n");
|
||||
assert(condition);
|
||||
@@ -1624,14 +1303,14 @@ Dsymbols *ConditionalDeclaration::include(Scope *sc, ScopeDsymbol *sd)
|
||||
|
||||
void ConditionalDeclaration::setScope(Scope *sc)
|
||||
{
|
||||
Dsymbols *d = include(sc, NULL);
|
||||
Dsymbols *d = include(sc, NULL);
|
||||
|
||||
//printf("\tConditionalDeclaration::setScope '%s', d = %p\n",toChars(), d);
|
||||
if (d)
|
||||
{
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{
|
||||
Dsymbol *s = d->tdata()[i];
|
||||
Dsymbol *s = d->tdata()[i];
|
||||
|
||||
s->setScope(sc);
|
||||
}
|
||||
@@ -1640,14 +1319,14 @@ void ConditionalDeclaration::setScope(Scope *sc)
|
||||
|
||||
void ConditionalDeclaration::importAll(Scope *sc)
|
||||
{
|
||||
Dsymbols *d = include(sc, NULL);
|
||||
Dsymbols *d = include(sc, NULL);
|
||||
|
||||
//printf("\tConditionalDeclaration::importAll '%s', d = %p\n",toChars(), d);
|
||||
if (d)
|
||||
{
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{
|
||||
Dsymbol *s = d->tdata()[i];
|
||||
Dsymbol *s = d->tdata()[i];
|
||||
|
||||
s->importAll(sc);
|
||||
}
|
||||
@@ -1664,7 +1343,7 @@ void ConditionalDeclaration::addComment(unsigned char *comment)
|
||||
|
||||
if (comment)
|
||||
{
|
||||
Dsymbols *d = decl;
|
||||
Dsymbols *d = decl;
|
||||
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
@@ -1673,7 +1352,7 @@ void ConditionalDeclaration::addComment(unsigned char *comment)
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s;
|
||||
|
||||
s = d->tdata()[i];
|
||||
s = d->tdata()[i];
|
||||
//printf("ConditionalDeclaration::addComment %s\n", s->toChars());
|
||||
s->addComment(comment);
|
||||
}
|
||||
@@ -1695,7 +1374,7 @@ void ConditionalDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
for (unsigned i = 0; i < decl->dim; i++)
|
||||
{
|
||||
Dsymbol *s = decl->tdata()[i];
|
||||
Dsymbol *s = decl->tdata()[i];
|
||||
|
||||
buf->writestring(" ");
|
||||
s->toCBuffer(buf, hgs);
|
||||
@@ -1711,7 +1390,7 @@ void ConditionalDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
buf->writenl();
|
||||
for (unsigned i = 0; i < elsedecl->dim; i++)
|
||||
{
|
||||
Dsymbol *s = elsedecl->tdata()[i];
|
||||
Dsymbol *s = elsedecl->tdata()[i];
|
||||
|
||||
buf->writestring(" ");
|
||||
s->toCBuffer(buf, hgs);
|
||||
@@ -1727,7 +1406,7 @@ void ConditionalDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
/***************************** StaticIfDeclaration ****************************/
|
||||
|
||||
StaticIfDeclaration::StaticIfDeclaration(Condition *condition,
|
||||
Dsymbols *decl, Dsymbols *elsedecl)
|
||||
Dsymbols *decl, Dsymbols *elsedecl)
|
||||
: ConditionalDeclaration(condition, decl, elsedecl)
|
||||
{
|
||||
//printf("StaticIfDeclaration::StaticIfDeclaration()\n");
|
||||
@@ -1785,7 +1464,7 @@ void StaticIfDeclaration::setScope(Scope *sc)
|
||||
|
||||
void StaticIfDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
Dsymbols *d = include(sc, sd);
|
||||
Dsymbols *d = include(sc, sd);
|
||||
|
||||
//printf("\tStaticIfDeclaration::semantic '%s', d = %p\n",toChars(), d);
|
||||
if (d)
|
||||
@@ -1797,7 +1476,7 @@ void StaticIfDeclaration::semantic(Scope *sc)
|
||||
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{
|
||||
Dsymbol *s = d->tdata()[i];
|
||||
Dsymbol *s = d->tdata()[i];
|
||||
|
||||
s->semantic(sc);
|
||||
}
|
||||
@@ -1849,8 +1528,8 @@ void CompileDeclaration::compileIt(Scope *sc)
|
||||
exp = exp->semantic(sc);
|
||||
exp = resolveProperties(sc, exp);
|
||||
exp = exp->optimize(WANTvalue | WANTinterpret);
|
||||
StringExp *se = exp->toString();
|
||||
if (!se)
|
||||
StringExp *se = exp->toString();
|
||||
if (!se)
|
||||
{ exp->error("argument to mixin must be a string, not (%s)", exp->toChars());
|
||||
}
|
||||
else
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "template.h"
|
||||
#include "attrib.h"
|
||||
#if IN_LLVM
|
||||
#include "../gen/enums.h"
|
||||
#include "../gen/pragma.h"
|
||||
#endif
|
||||
|
||||
/****************************** Dsymbol ******************************/
|
||||
|
||||
165
dmd/mars.h
165
dmd/mars.h
@@ -1,6 +1,6 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2011 by Digital Mars
|
||||
// Copyright (c) 1999-2011 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
@@ -29,7 +29,7 @@ Macros defined by the compiler, not the code:
|
||||
__DMC__ Digital Mars compiler
|
||||
_MSC_VER Microsoft compiler
|
||||
__GNUC__ Gnu compiler
|
||||
__clang__ Clang compiler
|
||||
__clang__ Clang compiler
|
||||
|
||||
Host operating system:
|
||||
_WIN32 Microsoft NT, Windows 95, Windows 98, Win32s,
|
||||
@@ -38,7 +38,7 @@ Macros defined by the compiler, not the code:
|
||||
linux Linux
|
||||
__APPLE__ Mac OSX
|
||||
__FreeBSD__ FreeBSD
|
||||
__OpenBSD__ OpenBSD
|
||||
__OpenBSD__ OpenBSD
|
||||
__sun&&__SVR4 Solaris, OpenSolaris (yes, both macros are necessary)
|
||||
|
||||
For the target systems, there are the target operating system and
|
||||
@@ -49,7 +49,7 @@ the target object file format:
|
||||
TARGET_LINUX Covers 32 and 64 bit linux
|
||||
TARGET_OSX Covers 32 and 64 bit Mac OSX
|
||||
TARGET_FREEBSD Covers 32 and 64 bit FreeBSD
|
||||
TARGET_OPENBSD Covers 32 and 64 bit OpenBSD
|
||||
TARGET_OPENBSD Covers 32 and 64 bit OpenBSD
|
||||
TARGET_SOLARIS Covers 32 and 64 bit Solaris
|
||||
TARGET_NET Covers .Net
|
||||
|
||||
@@ -58,7 +58,7 @@ the target object file format:
|
||||
|
||||
Target object module format:
|
||||
OMFOBJ Intel Object Module Format, used on Windows
|
||||
ELFOBJ Elf Object Module Format, used on linux, FreeBSD, OpenBSD and Solaris
|
||||
ELFOBJ Elf Object Module Format, used on linux, FreeBSD, OpenBSD and Solaris
|
||||
MACHOBJ Mach-O Object Module Format, used on Mac OSX
|
||||
|
||||
There are currently no macros for byte endianness order.
|
||||
@@ -84,20 +84,20 @@ the target object file format:
|
||||
|
||||
#ifndef IS_PRINTF
|
||||
# ifdef __GNUC__
|
||||
# define IS_PRINTF(FMTARG) __attribute__((__format__ (__printf__, (FMTARG), (FMTARG)+1) ))
|
||||
# define IS_PRINTF(FMTARG) __attribute__((__format__ (__printf__, (FMTARG), (FMTARG)+1) ))
|
||||
# else
|
||||
# define IS_PRINTF(FMTARG)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef IS_VPRINTF
|
||||
# ifdef __GNUC__
|
||||
# define IS_VPRINTF(FMTARG) __attribute__((__format__ (__printf__, (FMTARG), 0) ))
|
||||
# else
|
||||
# define IS_VPRINTF(FMTARG)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef IS_VPRINTF
|
||||
# ifdef __GNUC__
|
||||
# define IS_VPRINTF(FMTARG) __attribute__((__format__ (__printf__, (FMTARG), 0) ))
|
||||
# else
|
||||
# define IS_VPRINTF(FMTARG)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef IN_GCC
|
||||
/* Changes for the GDC compiler by David Friedman */
|
||||
#endif
|
||||
@@ -110,23 +110,23 @@ the target object file format:
|
||||
#define MODULEINFO_IS_STRUCT DMDV2 // if ModuleInfo is a struct rather than a class
|
||||
|
||||
// Set if C++ mangling is done by the front end
|
||||
#define CPP_MANGLE (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS))
|
||||
#define CPP_MANGLE (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS))
|
||||
|
||||
/* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD, TARGET_OPENBSD and
|
||||
/* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD, TARGET_OPENBSD and
|
||||
* TARGET_SOLARIS, which are
|
||||
* set on the command line via the compiler makefile.
|
||||
*/
|
||||
|
||||
#if _WIN32
|
||||
#ifndef TARGET_WINDOS
|
||||
#ifndef TARGET_WINDOS
|
||||
#define TARGET_WINDOS 1 // Windows dmd generates Windows targets
|
||||
#endif
|
||||
#ifndef OMFOBJ
|
||||
#define OMFOBJ TARGET_WINDOS
|
||||
#endif
|
||||
#endif
|
||||
#ifndef OMFOBJ
|
||||
#define OMFOBJ TARGET_WINDOS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
|
||||
#if TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
|
||||
#ifndef ELFOBJ
|
||||
#define ELFOBJ 1
|
||||
#endif
|
||||
@@ -172,11 +172,11 @@ enum OS
|
||||
|
||||
typedef unsigned char ubyte;
|
||||
|
||||
// Can't include arraytypes.h here, need to declare these directly.
|
||||
template <typename TYPE> struct ArrayBase;
|
||||
//typedef ArrayBase<struct Identifier> Identifiers;
|
||||
typedef ArrayBase<char> Strings;
|
||||
|
||||
// Can't include arraytypes.h here, need to declare these directly.
|
||||
template <typename TYPE> struct ArrayBase;
|
||||
//typedef ArrayBase<struct Identifier> Identifiers;
|
||||
typedef ArrayBase<char> Strings;
|
||||
|
||||
// Put command line switches in here
|
||||
struct Param
|
||||
{
|
||||
@@ -190,7 +190,7 @@ struct Param
|
||||
char optimizeLevel; // optimization level
|
||||
#endif
|
||||
char vtls; // identify thread local variables
|
||||
// KN Start merge conflict
|
||||
// KN Start merge conflict
|
||||
ARCH cpu; // target CPU
|
||||
OS os; // target OS
|
||||
bool is64bit; // generate 64 bit code
|
||||
@@ -205,52 +205,53 @@ struct Param
|
||||
bool useUnitTests; // generate unittest code
|
||||
bool useInline; // inline expand functions
|
||||
ubyte warnings; // enable warnings
|
||||
ubyte Dversion; // D version number
|
||||
// KN End merge conflict
|
||||
#if 0
|
||||
char symdebug; // insert debug symbolic information
|
||||
char alwaysframe; // always emit standard stack frame
|
||||
char optimize; // run optimizer
|
||||
char map; // generate linker .map file
|
||||
char cpu; // target CPU
|
||||
char is64bit; // generate 64 bit code
|
||||
char isLinux; // generate code for linux
|
||||
char isOSX; // generate code for Mac OSX
|
||||
char isWindows; // generate code for Windows
|
||||
char isFreeBSD; // generate code for FreeBSD
|
||||
char isOPenBSD; // generate code for OpenBSD
|
||||
char isSolaris; // generate code for Solaris
|
||||
char scheduler; // which scheduler to use
|
||||
char useDeprecated; // allow use of deprecated features
|
||||
char useAssert; // generate runtime code for assert()'s
|
||||
char useInvariants; // generate class invariant checks
|
||||
char useIn; // generate precondition checks
|
||||
char useOut; // generate postcondition checks
|
||||
char useArrayBounds; // 0: no array bounds checks
|
||||
// 1: array bounds checks for safe functions only
|
||||
// 2: array bounds checks for all functions
|
||||
char noboundscheck; // no array bounds checking at all
|
||||
char useSwitchError; // check for switches without a default
|
||||
char useUnitTests; // generate unittest code
|
||||
char useInline; // inline expand functions
|
||||
char release; // build release version
|
||||
char preservePaths; // !=0 means don't strip path from source file
|
||||
char warnings; // 0: enable warnings
|
||||
#endif
|
||||
// KN End merge conflict
|
||||
#if 0
|
||||
char symdebug; // insert debug symbolic information
|
||||
char alwaysframe; // always emit standard stack frame
|
||||
char optimize; // run optimizer
|
||||
char map; // generate linker .map file
|
||||
char cpu; // target CPU
|
||||
char is64bit; // generate 64 bit code
|
||||
char isLinux; // generate code for linux
|
||||
char isOSX; // generate code for Mac OSX
|
||||
char isWindows; // generate code for Windows
|
||||
char isFreeBSD; // generate code for FreeBSD
|
||||
char isOPenBSD; // generate code for OpenBSD
|
||||
char isSolaris; // generate code for Solaris
|
||||
char scheduler; // which scheduler to use
|
||||
char useDeprecated; // allow use of deprecated features
|
||||
char useAssert; // generate runtime code for assert()'s
|
||||
char useInvariants; // generate class invariant checks
|
||||
char useIn; // generate precondition checks
|
||||
char useOut; // generate postcondition checks
|
||||
char useArrayBounds; // 0: no array bounds checks
|
||||
// 1: array bounds checks for safe functions only
|
||||
// 2: array bounds checks for all functions
|
||||
char noboundscheck; // no array bounds checking at all
|
||||
char useSwitchError; // check for switches without a default
|
||||
char useUnitTests; // generate unittest code
|
||||
char useInline; // inline expand functions
|
||||
char release; // build release version
|
||||
char preservePaths; // !=0 means don't strip path from source file
|
||||
char warnings; // 0: enable warnings
|
||||
#endif
|
||||
// 1: warnings as errors
|
||||
// 2: informational warnings (no errors)
|
||||
ubyte Dversion; // D version number
|
||||
bool ignoreUnsupportedPragmas; // rather than error on them
|
||||
char safe; // enforce safe memory model
|
||||
|
||||
char *argv0; // program name
|
||||
Strings *imppath; // array of char*'s of where to look for import modules
|
||||
Strings *fileImppath; // array of char*'s of where to look for file import modules
|
||||
char *objdir; // .obj/.lib file output directory
|
||||
Strings *imppath; // array of char*'s of where to look for import modules
|
||||
Strings *fileImppath; // array of char*'s of where to look for file import modules
|
||||
char *objdir; // .obj/.lib file output directory
|
||||
char *objname; // .obj file output name
|
||||
|
||||
bool doDocComments; // process embedded documentation comments
|
||||
char *docdir; // write documentation file to docdir directory
|
||||
char *docname; // write documentation file to docname
|
||||
Strings *ddocfiles; // macro include files for Ddoc
|
||||
Strings *ddocfiles; // macro include files for Ddoc
|
||||
|
||||
bool doHdrGeneration; // process embedded documentation comments
|
||||
char *hdrdir; // write 'header' file to docdir directory
|
||||
@@ -260,15 +261,15 @@ struct Param
|
||||
char *xfilename; // write JSON file to xfilename
|
||||
|
||||
unsigned debuglevel; // debug level
|
||||
Strings *debugids; // debug identifiers
|
||||
Strings *debugids; // debug identifiers
|
||||
|
||||
unsigned versionlevel; // version level
|
||||
Strings *versionids; // version identifiers
|
||||
Strings *versionids; // version identifiers
|
||||
|
||||
bool dump_source;
|
||||
|
||||
Strings *defaultlibnames; // default libraries for non-debug builds
|
||||
Strings *debuglibnames; // default libraries for debug builds
|
||||
Strings *defaultlibnames; // default libraries for non-debug builds
|
||||
Strings *debuglibnames; // default libraries for debug builds
|
||||
|
||||
char *moduleDepsFile; // filename for deps output
|
||||
OutBuffer *moduleDeps; // contents to be written to deps file
|
||||
@@ -286,9 +287,9 @@ struct Param
|
||||
bool run; // run resulting executable
|
||||
|
||||
// Linker stuff
|
||||
Strings *objfiles;
|
||||
Strings *linkswitches;
|
||||
Strings *libfiles;
|
||||
Strings *objfiles;
|
||||
Strings *linkswitches;
|
||||
Strings *libfiles;
|
||||
char *deffile;
|
||||
char *resfile;
|
||||
char *exefile;
|
||||
@@ -332,8 +333,8 @@ struct Global
|
||||
const char *map_ext; // for .map files
|
||||
const char *copyright;
|
||||
const char *written;
|
||||
Strings *path; // Array of char*'s which form the import lookup path
|
||||
Strings *filePath; // Array of char*'s which form the file import lookup path
|
||||
Strings *path; // Array of char*'s which form the import lookup path
|
||||
Strings *filePath; // Array of char*'s which form the file import lookup path
|
||||
int structalign;
|
||||
const char *version;
|
||||
char *ldc_version;
|
||||
@@ -343,15 +344,15 @@ struct Global
|
||||
unsigned errors; // number of errors reported so far
|
||||
unsigned warnings; // number of warnings reported so far
|
||||
unsigned gag; // !=0 means gag reporting of errors & warnings
|
||||
unsigned gaggedErrors; // number of errors reported while gagged
|
||||
|
||||
// Start gagging. Return the current number of gagged errors
|
||||
unsigned startGagging();
|
||||
|
||||
/* End gagging, restoring the old gagged state.
|
||||
* Return true if errors occured while gagged.
|
||||
*/
|
||||
bool endGagging(unsigned oldGagged);
|
||||
unsigned gaggedErrors; // number of errors reported while gagged
|
||||
|
||||
// Start gagging. Return the current number of gagged errors
|
||||
unsigned startGagging();
|
||||
|
||||
/* End gagging, restoring the old gagged state.
|
||||
* Return true if errors occured while gagged.
|
||||
*/
|
||||
bool endGagging(unsigned oldGagged);
|
||||
|
||||
Global();
|
||||
};
|
||||
|
||||
348
dmd2/attrib.c
348
dmd2/attrib.c
@@ -29,16 +29,8 @@
|
||||
#if TARGET_NET
|
||||
#include "frontend.net/pragma.h"
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
#include "../gen/enums.h"
|
||||
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
||||
static llvm::cl::opt<bool> ignoreUnsupportedPragmas("ignore",
|
||||
llvm::cl::desc("Ignore unsupported pragmas"),
|
||||
llvm::cl::ZeroOrMore);
|
||||
|
||||
#include "../gen/pragma.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -944,20 +936,6 @@ const char *AnonDeclaration::kind()
|
||||
|
||||
/********************************* PragmaDeclaration ****************************/
|
||||
|
||||
static bool parseStringExp(Expression* e, std::string& res)
|
||||
{
|
||||
StringExp *s = NULL;
|
||||
|
||||
e = e->optimize(WANTvalue);
|
||||
if (e->op == TOKstring && (s = (StringExp *)e))
|
||||
{
|
||||
char* str = (char*)s->string;
|
||||
res = str;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PragmaDeclaration::PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Dsymbols *decl)
|
||||
: AttribDeclaration(decl)
|
||||
{
|
||||
@@ -1015,7 +993,7 @@ void PragmaDeclaration::semantic(Scope *sc)
|
||||
{ // Should be merged with PragmaStatement
|
||||
|
||||
#if IN_LLVM
|
||||
int llvm_internal = 0;
|
||||
Pragma llvm_internal = LLVMnone;
|
||||
std::string arg1str;
|
||||
#endif
|
||||
|
||||
@@ -1129,191 +1107,13 @@ void PragmaDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
}
|
||||
#endif // TARGET_NET
|
||||
// LDC
|
||||
#if IN_LLVM
|
||||
|
||||
// pragma(intrinsic, "string") { funcdecl(s) }
|
||||
else if (ident == Id::intrinsic)
|
||||
else if ((llvm_internal = DtoGetPragma(sc, this, arg1str)) != LLVMnone)
|
||||
{
|
||||
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;
|
||||
// nothing to do anymore
|
||||
}
|
||||
|
||||
// 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)
|
||||
#endif
|
||||
else if (global.params.ignoreUnsupportedPragmas)
|
||||
{
|
||||
if (global.params.verbose)
|
||||
{
|
||||
@@ -1358,142 +1158,10 @@ void PragmaDeclaration::semantic(Scope *sc)
|
||||
|
||||
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();
|
||||
DtoCheckPragma(this, s, llvm_internal, arg1str);
|
||||
#endif
|
||||
}
|
||||
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;
|
||||
|
||||
|
||||
@@ -31,9 +31,8 @@
|
||||
#include "import.h"
|
||||
#include "template.h"
|
||||
#include "attrib.h"
|
||||
|
||||
#if IN_LLVM
|
||||
#include "../gen/enums.h"
|
||||
#include "../gen/pragma.h"
|
||||
#endif
|
||||
|
||||
/****************************** Dsymbol ******************************/
|
||||
|
||||
@@ -206,6 +206,7 @@ struct Param
|
||||
bool useInline; // inline expand functions
|
||||
ubyte warnings; // enable warnings
|
||||
ubyte Dversion; // D version number
|
||||
bool ignoreUnsupportedPragmas; // rather than error on them
|
||||
char enforcePropertySyntax;
|
||||
|
||||
char *argv0; // program name
|
||||
|
||||
@@ -73,6 +73,11 @@ static cl::opt<ubyte, true> warnings(
|
||||
cl::location(global.params.warnings),
|
||||
cl::init(0));
|
||||
|
||||
static cl::opt<bool, true> ignoreUnsupportedPragmas("ignore",
|
||||
cl::desc("Ignore unsupported pragmas"),
|
||||
cl::ZeroOrMore,
|
||||
cl::location(global.params.ignoreUnsupportedPragmas));
|
||||
|
||||
static cl::opt<ubyte, true> debugInfo(
|
||||
cl::desc("Generating debug information:"),
|
||||
cl::ZeroOrMore,
|
||||
|
||||
18
gen/enums.h
18
gen/enums.h
@@ -1,18 +0,0 @@
|
||||
enum
|
||||
{
|
||||
LLVMnone,
|
||||
LLVMintrinsic,
|
||||
LLVMno_typeinfo,
|
||||
LLVMno_moduleinfo,
|
||||
LLVMalloca,
|
||||
LLVMva_start,
|
||||
LLVMva_copy,
|
||||
LLVMva_end,
|
||||
LLVMva_arg,
|
||||
LLVMinline_asm,
|
||||
LLVMfence,
|
||||
LLVMatomic_store,
|
||||
LLVMatomic_load,
|
||||
LLVMatomic_cmp_xchg,
|
||||
LLVMatomic_rmw
|
||||
};
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "gen/abi.h"
|
||||
#include "gen/nested.h"
|
||||
#include "gen/cl_options.h"
|
||||
#include "gen/pragma.h"
|
||||
|
||||
using namespace llvm::Attribute;
|
||||
|
||||
|
||||
347
gen/pragma.cpp
Normal file
347
gen/pragma.cpp
Normal file
@@ -0,0 +1,347 @@
|
||||
#include "pragma.h"
|
||||
#include "attrib.h"
|
||||
#include "id.h"
|
||||
#include "expression.h"
|
||||
#include "scope.h"
|
||||
#include "module.h"
|
||||
#include "declaration.h"
|
||||
#include "template.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
||||
static bool parseStringExp(Expression* e, std::string& res)
|
||||
{
|
||||
StringExp *s = NULL;
|
||||
|
||||
e = e->optimize(WANTvalue);
|
||||
if (e->op == TOKstring && (s = (StringExp *)e))
|
||||
{
|
||||
char* str = (char*)s->string;
|
||||
res = str;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str)
|
||||
{
|
||||
Identifier *ident = decl->ident;
|
||||
Expressions *args = decl->args;
|
||||
|
||||
// pragma(intrinsic, "string") { funcdecl(s) }
|
||||
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();
|
||||
}
|
||||
return LLVMintrinsic;
|
||||
}
|
||||
|
||||
// pragma(notypeinfo) { typedecl(s) }
|
||||
else if (ident == Id::no_typeinfo)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
return LLVMno_typeinfo;
|
||||
}
|
||||
|
||||
// pragma(nomoduleinfo) ;
|
||||
else if (ident == Id::no_moduleinfo)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
return LLVMno_moduleinfo;
|
||||
}
|
||||
|
||||
// pragma(alloca) { funcdecl(s) }
|
||||
else if (ident == Id::Alloca)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
return LLVMalloca;
|
||||
}
|
||||
|
||||
// pragma(va_start) { templdecl(s) }
|
||||
else if (ident == Id::vastart)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
return LLVMva_start;
|
||||
}
|
||||
|
||||
// pragma(va_copy) { funcdecl(s) }
|
||||
else if (ident == Id::vacopy)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
return LLVMva_copy;
|
||||
}
|
||||
|
||||
// pragma(va_end) { funcdecl(s) }
|
||||
else if (ident == Id::vaend)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
return LLVMva_end;
|
||||
}
|
||||
|
||||
// pragma(va_arg) { templdecl(s) }
|
||||
else if (ident == Id::vaarg)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
return LLVMva_arg;
|
||||
}
|
||||
|
||||
// pragma(fence) { funcdecl(s) }
|
||||
else if (ident == Id::fence)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
return LLVMfence;
|
||||
}
|
||||
|
||||
// pragma(atomic_load) { templdecl(s) }
|
||||
else if (ident == Id::atomic_load)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
return LLVMatomic_load;
|
||||
}
|
||||
|
||||
// pragma(atomic_store) { templdecl(s) }
|
||||
else if (ident == Id::atomic_store)
|
||||
{
|
||||
if (args && args->dim > 0)
|
||||
{
|
||||
error("takes no parameters");
|
||||
fatal();
|
||||
}
|
||||
return 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();
|
||||
}
|
||||
return 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();
|
||||
}
|
||||
return 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();
|
||||
}
|
||||
return LLVMinline_asm;
|
||||
}
|
||||
|
||||
return LLVMnone;
|
||||
}
|
||||
|
||||
void DtoCheckPragma(PragmaDeclaration *decl, Dsymbol *s,
|
||||
Pragma llvm_internal, const std::string &arg1str)
|
||||
{
|
||||
if (llvm_internal == LLVMnone)
|
||||
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;
|
||||
((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());
|
||||
}
|
||||
}
|
||||
33
gen/pragma.h
Normal file
33
gen/pragma.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef PRAGMA_H
|
||||
#define PRAGMA_H
|
||||
|
||||
#include <string>
|
||||
|
||||
struct PragmaDeclaration;
|
||||
struct Dsymbol;
|
||||
struct Scope;
|
||||
|
||||
enum Pragma
|
||||
{
|
||||
LLVMnone,
|
||||
LLVMintrinsic,
|
||||
LLVMno_typeinfo,
|
||||
LLVMno_moduleinfo,
|
||||
LLVMalloca,
|
||||
LLVMva_start,
|
||||
LLVMva_copy,
|
||||
LLVMva_end,
|
||||
LLVMva_arg,
|
||||
LLVMinline_asm,
|
||||
LLVMfence,
|
||||
LLVMatomic_store,
|
||||
LLVMatomic_load,
|
||||
LLVMatomic_cmp_xchg,
|
||||
LLVMatomic_rmw
|
||||
};
|
||||
|
||||
Pragma DtoGetPragma(Scope *sc, PragmaDeclaration *decl, std::string &arg1str);
|
||||
void DtoCheckPragma(PragmaDeclaration *decl, Dsymbol *sym,
|
||||
Pragma llvm_internal, const std::string &arg1str);
|
||||
|
||||
#endif // PRAGMA_H
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "gen/utils.h"
|
||||
#include "gen/warnings.h"
|
||||
#include "gen/optimizer.h"
|
||||
#include "gen/pragma.h"
|
||||
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "gen/complex.h"
|
||||
#include "gen/llvmhelpers.h"
|
||||
#include "gen/linkage.h"
|
||||
#include "gen/pragma.h"
|
||||
|
||||
#include "ir/irtype.h"
|
||||
#include "ir/irtypeclass.h"
|
||||
|
||||
@@ -162,6 +162,4 @@ void DtoAggrCopy(LLValue* dst, LLValue* src);
|
||||
*/
|
||||
void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device=false);
|
||||
|
||||
#include "enums.h"
|
||||
|
||||
#endif // LDC_GEN_TOLLVM_H
|
||||
|
||||
Reference in New Issue
Block a user