1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
//===-- gen/ldctraits.d - LDC-specific __traits handling ----------*- D -*-===//
//
// LDC – the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//
module gen.ldctraits;
import dmd.arraytypes;
import dmd.dscope;
import dmd.dtemplate;
import dmd.expression;
import dmd.expressionsem;
import dmd.errors;
import dmd.id;
import dmd.mtype;
extern(C++) struct Dstring
{
size_t length;
const(char)* ptr;
}
extern(C++) Dstring traitsGetTargetCPU();
extern(C++) bool traitsTargetHasFeature(Dstring feature);
Expression semanticTraitsLDC(TraitsExp e, Scope* sc)
{
size_t arg_count = e.args ? e.args.dim : 0;
if (e.ident == Id.targetCPU)
{
if (arg_count != 0)
{
e.warning("ignoring arguments for __traits %s", e.ident.toChars());
}
auto cpu = traitsGetTargetCPU();
auto se = new StringExp(e.loc, cpu.ptr[0 .. cpu.length]);
return se.expressionSemantic(sc);
}
if (e.ident == Id.targetHasFeature)
{
if (arg_count != 1)
{
e.error("__traits %s expects one argument, not %u", e.ident.toChars(), cast(uint)arg_count);
return ErrorExp.get();
}
auto ex = isExpression((*e.args)[0]);
if (!ex)
{
e.error("expression expected as argument of __traits %s", e.ident.toChars());
return ErrorExp.get();
}
ex = ex.ctfeInterpret();
StringExp se = ex.toStringExp();
if (!se || se.len == 0)
{
e.error("string expected as argument of __traits %s instead of %s", e.ident.toChars(), ex.toChars());
return ErrorExp.get();
}
se = se.toUTF8(sc);
auto str = se.peekString();
auto featureFound = traitsTargetHasFeature(Dstring(str.length, str.ptr));
return new IntegerExp(e.loc, featureFound ? 1 : 0, Type.tbool);
}
return null;
}
|