1 
2 module llvm.c.versions;
3 
4 private
5 {
6 	import std.conv : to;
7 	import std.algorithm;
8 	import std.range;
9 }
10 
11 /// Makes an ordered identifier from a major, minor, and patch number
12 pure nothrow @nogc
13 ulong LLVMDVersion(ushort major, ushort minor, ushort patch)
14 {
15 	return cast(ulong)(major) << (ushort.sizeof*2*8) | cast(ulong)(minor) << (ushort.sizeof*8) | cast(ulong)(patch);
16 }
17 
18 private enum KnownVersions = [
19 	[3,7,1],
20 	[3,7,0],
21 	[3,6,2],
22 	[3,6,1],
23 	[3,6,0],
24 	[3,5,2],
25 	[3,5,1],
26 	[3,5,0],
27 	[3,4,2],
28 	[3,4,1],
29 	[3,4,0],
30 	[3,3,0],
31 	[3,2,0],
32 	[3,1,0],
33 ];
34 
35 mixin(KnownVersions.map!(ver =>
36 	q{version(LLVM_%MAJOR_%MINOR_%PATCH) {
37 			enum LLVM_VERSION_MAJOR = %MAJOR;
38 			enum LLVM_VERSION_MINOR = %MINOR;
39 			enum LLVM_VERSION_PATCH = %PATCH;
40 		}}.replace("%MAJOR", ver[0].to!string).replace("%MINOR", ver[1].to!string).replace("%PATCH", ver[2].to!string)
41 	).join("else\n") ~
42 	q{else {
43 		enum LLVM_VERSION_MAJOR = KnownVersions[0][0];
44 		enum LLVM_VERSION_MINOR = KnownVersions[0][1];
45 		enum LLVM_VERSION_PATCH = KnownVersions[0][2];
46 	}}
47 );
48 
49 /// LLVM Version that LLVM-D was compiled with
50 enum LLVM_Version = LLVMDVersion(LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, LLVM_VERSION_PATCH);
51 /// ditto
52 enum LLVM_VersionString = LLVM_VERSION_MAJOR.to!string ~ "." ~ LLVM_VERSION_MINOR.to!string ~ "." ~ LLVM_VERSION_PATCH.to!string;
53 
54 //qualifiers is in the form ["+", "3", "2, "0", "-", "3", "5", "0"]
55 bool matchVersionQualifiers(string[] qualifiers)
56 {
57 	while(qualifiers.length > 0)
58 	{
59 		string op = qualifiers[0];
60 		ulong ver = LLVMDVersion(qualifiers[1].to!ushort, qualifiers[2].to!ushort, qualifiers[3].to!ushort);
61 		if((op == "+" && LLVM_Version < ver) ||
62 		   (op == "-" && LLVM_Version >= ver))
63 		{
64 			return false;
65 		}
66 		qualifiers = qualifiers[4 .. $];
67 	}
68 	return true;
69 }