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; 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 private: 51 string virtual_path; 52 53 static template toInternalHeader(string file) { 54 enum toInternalHeader = InternalHeader(file, import(file)); 55 } 56 57 // dfmt off 58 enum internalHeaders = [ 59 staticMap!(toInternalHeader, 60 "float.h", 61 "limits.h", 62 "stdalign.h", 63 "stdarg.h", 64 "stdbool.h", 65 "stddef.h", 66 "stdint.h", 67 "__stddef_max_align_t.h" 68 ) 69 ]; 70 // dfmt on 71 } 72 73 private: 74 75 string virtualPath() @safe pure nothrow { 76 import std.path : buildPath; 77 78 version (Windows) { 79 enum root = `C:\`; 80 } else { 81 enum root = "/"; 82 } 83 enum root_suffix = "dextool_clang"; 84 85 return buildPath(root, uniquePathId, root_suffix); 86 } 87 88 struct InternalHeader { 89 string filename; 90 string content; 91 } 92 93 struct HeaderResult { 94 private InternalHeader[] hdrs; 95 private string virtual_path; 96 private size_t idx; 97 98 InternalHeader front() @safe pure nothrow { 99 import std.path : buildPath; 100 101 assert(!empty, "Can't get front of an empty range"); 102 auto path = buildPath(virtual_path, hdrs[idx].filename); 103 return InternalHeader(path, hdrs[idx].content); 104 } 105 106 void popFront() @safe pure nothrow { 107 assert(!empty, "Can't pop front of an empty range"); 108 ++idx; 109 } 110 111 bool empty() @safe pure nothrow const @nogc { 112 return idx == hdrs.length; 113 } 114 }