Refactoring: moved ldc specific code from dmd/attrib.c and dmd2/attrib.c into gen/pragma.cpp

This commit is contained in:
Alexey Prokhin
2012-02-15 13:16:06 +04:00
parent 72d510cb5e
commit 4d3ba3594c
14 changed files with 597 additions and 881 deletions
+8 -340
View File
@@ -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;
+1 -2
View File
@@ -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 ******************************/
+1
View File
@@ -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