1 /** 2 * Copyright: Copyright (c) 2015 Jacob Carlborg. All rights reserved. 3 * Authors: Jacob Carlborg 4 * Version: 1.1 5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 6 * 7 * History: 8 * 1.0 Initial created: Jan 31, 2015 $(BR) 9 * Jacob Carlborg 10 * 1.1 updated to clang 3.6 with additional internal header $(BR) 11 * Joakim Brännström 12 */ 13 module clang.Compiler; 14 15 @safe: 16 17 private const(string) uniquePathId; 18 19 static this() { 20 import std.conv : text; 21 import std.random; 22 23 // Keep the identifier the same while running. 24 // Easier for the user to reason about what it is, where it comes from. 25 uniquePathId = text(uniform(1, 10_000_000)); 26 } 27 28 /** Clang specific in-memory files. 29 * 30 * Imported into the binary during compilation time. 31 */ 32 struct Compiler { 33 import std.algorithm : any, map, joiner; 34 import std.path : buildPath; 35 import std.meta : staticMap; 36 37 HeaderResult extraHeaders() { 38 return HeaderResult(internalHeaders, extraIncludePath); 39 } 40 41 /// Returns: The virtual path the internal headers are located at. 42 string extraIncludePath() { 43 if (virtual_path is null) { 44 virtual_path = virtualPath; 45 } 46 47 return virtual_path; 48 } 49 50 string[] extraIncludeFlags() { 51 import std.algorithm; 52 import std.array; 53 54 return [extraIncludePath].map!(x => ["-isystem", x]).joiner.array; 55 } 56 57 private: 58 string virtual_path; 59 60 static template toInternalHeader(string file) { 61 enum toInternalHeader = InternalHeader(file, import(file)); 62 } 63 64 // dfmt off 65 enum internalHeaders = [ 66 staticMap!(toInternalHeader, 67 "__stddef_max_align_t.h", 68 "float.h", 69 "limits.h", 70 "stdalign.h", 71 "stdarg.h", 72 "stdbool.h", 73 "stddef.h", 74 "stdint.h", 75 ) 76 ]; 77 // dfmt on 78 } 79 80 private: 81 82 string virtualPath() @safe pure nothrow { 83 import std.path : buildPath; 84 85 version (Windows) { 86 enum root = `C:\`; 87 } else { 88 enum root = "/"; 89 } 90 enum root_suffix = "dextool_clang"; 91 92 return buildPath(root, uniquePathId, root_suffix); 93 } 94 95 struct InternalHeader { 96 string filename; 97 string content; 98 } 99 100 struct HeaderResult { 101 private InternalHeader[] hdrs; 102 private string virtual_path; 103 private size_t idx; 104 105 InternalHeader front() @safe pure nothrow { 106 import std.path : buildPath; 107 108 assert(!empty, "Can't get front of an empty range"); 109 auto path = buildPath(virtual_path, hdrs[idx].filename); 110 return InternalHeader(path, hdrs[idx].content); 111 } 112 113 void popFront() @safe pure nothrow { 114 assert(!empty, "Can't pop front of an empty range"); 115 ++idx; 116 } 117 118 bool empty() @safe pure nothrow const @nogc { 119 return idx == hdrs.length; 120 } 121 }