authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-13 11:53:20-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-13 11:53:20-05:00
loge7ab2bc5534a53c57c900618ec2411542dc50f69
tree42c572bf7414f59a98cd40a37e7d2f5d94955084
parent7903a758a44d1a253f17a4a2383f36b5fdad8545
parentc721354b73508ec53bf72d8e7fb304147676625d

Merge remote-tracking branch 'origin/master' into llvm6


4 files changed, 146 insertions(+), 57 deletions(-)

src/zig_llvm.cpp+8-27
...@@ -43,31 +43,8 @@...@@ -43,31 +43,8 @@
4343
44#include <stdlib.h>44#include <stdlib.h>
4545
46#if defined(_MSC_VER)
47#define ATTRIBUTE_RETURNS_NOALIAS __declspec(restrict)
48#else
49#define ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
50#endif
51
52using namespace llvm;46using namespace llvm;
5347
54template<typename T, typename... Args>
55ATTRIBUTE_RETURNS_NOALIAS static inline T * create(Args... args) {
56 T * ptr = reinterpret_cast<T*>(malloc(sizeof(T)));
57 if (ptr == nullptr)
58 return nullptr;
59 new (ptr) T(args...);
60 return ptr;
61}
62
63template<typename T>
64static inline void destroy(T * ptr) {
65 if (ptr != nullptr) {
66 ptr[0].~T();
67 }
68 free(ptr);
69}
70
71void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) {48void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) {
72 initializeLoopStrengthReducePass(*unwrap(R));49 initializeLoopStrengthReducePass(*unwrap(R));
73}50}
...@@ -116,7 +93,11 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM...@@ -116,7 +93,11 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
11693
117 Module* module = unwrap(module_ref);94 Module* module = unwrap(module_ref);
11895
119 PassManagerBuilder *PMBuilder = create<PassManagerBuilder>();96 PassManagerBuilder *PMBuilder = new(std::nothrow) PassManagerBuilder();
97 if (PMBuilder == nullptr) {
98 *error_message = strdup("memory allocation failure");
99 return true;
100 }
120 PMBuilder->OptLevel = target_machine->getOptLevel();101 PMBuilder->OptLevel = target_machine->getOptLevel();
121 PMBuilder->SizeLevel = 0;102 PMBuilder->SizeLevel = 0;
122103
...@@ -150,7 +131,8 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM...@@ -150,7 +131,8 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
150131
151 // Set up the per-function pass manager.132 // Set up the per-function pass manager.
152 legacy::FunctionPassManager FPM = legacy::FunctionPassManager(module);133 legacy::FunctionPassManager FPM = legacy::FunctionPassManager(module);
153 FPM.add(create<TargetLibraryInfoWrapperPass>(tlii));134 auto tliwp = new(std::nothrow) TargetLibraryInfoWrapperPass(tlii);
135 FPM.add(tliwp);
154 FPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));136 FPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));
155 if (assertions_on) {137 if (assertions_on) {
156 FPM.add(createVerifierPass());138 FPM.add(createVerifierPass());
...@@ -446,10 +428,9 @@ unsigned ZigLLVMTag_DW_union_type(void) {...@@ -446,10 +428,9 @@ unsigned ZigLLVMTag_DW_union_type(void) {
446}428}
447429
448ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) {430ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) {
449 DIBuilder *di_builder = reinterpret_cast<DIBuilder*>(malloc(sizeof(DIBuilder)));431 DIBuilder *di_builder = new(std::nothrow) DIBuilder(*unwrap(module), allow_unresolved);
450 if (di_builder == nullptr)432 if (di_builder == nullptr)
451 return nullptr;433 return nullptr;
452 new (di_builder) DIBuilder(*unwrap(module), allow_unresolved);
453 return reinterpret_cast<ZigLLVMDIBuilder *>(di_builder);434 return reinterpret_cast<ZigLLVMDIBuilder *>(di_builder);
454}435}
455436
std/zig/ast.zig+17-15
...@@ -18,6 +18,7 @@ pub const Node = struct {...@@ -18,6 +18,7 @@ pub const Node = struct {
18 PrefixOp,18 PrefixOp,
19 IntegerLiteral,19 IntegerLiteral,
20 FloatLiteral,20 FloatLiteral,
21 BuiltinCall,
21 };22 };
2223
23 pub fn iterate(base: &Node, index: usize) ?&Node {24 pub fn iterate(base: &Node, index: usize) ?&Node {
...@@ -32,21 +33,7 @@ pub const Node = struct {...@@ -32,21 +33,7 @@ pub const Node = struct {
32 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).iterate(index),33 Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).iterate(index),
33 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).iterate(index),34 Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).iterate(index),
34 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).iterate(index),35 Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).iterate(index),
35 };36 Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).iterate(index),
36 }
37
38 pub fn destroy(base: &Node, allocator: &mem.Allocator) void {
39 return switch (base.id) {
40 Id.Root => allocator.destroy(@fieldParentPtr(NodeRoot, "base", base)),
41 Id.VarDecl => allocator.destroy(@fieldParentPtr(NodeVarDecl, "base", base)),
42 Id.Identifier => allocator.destroy(@fieldParentPtr(NodeIdentifier, "base", base)),
43 Id.FnProto => allocator.destroy(@fieldParentPtr(NodeFnProto, "base", base)),
44 Id.ParamDecl => allocator.destroy(@fieldParentPtr(NodeParamDecl, "base", base)),
45 Id.Block => allocator.destroy(@fieldParentPtr(NodeBlock, "base", base)),
46 Id.InfixOp => allocator.destroy(@fieldParentPtr(NodeInfixOp, "base", base)),
47 Id.PrefixOp => allocator.destroy(@fieldParentPtr(NodePrefixOp, "base", base)),
48 Id.IntegerLiteral => allocator.destroy(@fieldParentPtr(NodeIntegerLiteral, "base", base)),
49 Id.FloatLiteral => allocator.destroy(@fieldParentPtr(NodeFloatLiteral, "base", base)),
50 };37 };
51 }38 }
52};39};
...@@ -269,3 +256,18 @@ pub const NodeFloatLiteral = struct {...@@ -269,3 +256,18 @@ pub const NodeFloatLiteral = struct {
269 return null;256 return null;
270 }257 }
271};258};
259
260pub const NodeBuiltinCall = struct {
261 base: Node,
262 builtin_token: Token,
263 params: ArrayList(&Node),
264
265 pub fn iterate(self: &NodeBuiltinCall, index: usize) ?&Node {
266 var i = index;
267
268 if (i < self.params.len) return self.params.at(i);
269 i -= self.params.len;
270
271 return null;
272 }
273};
std/zig/parser.zig+2-1
...@@ -95,7 +95,8 @@ pub const Parser = struct {...@@ -95,7 +95,8 @@ pub const Parser = struct {
95 };95 };
9696
97 /// Returns an AST tree, allocated with the parser's allocator.97 /// Returns an AST tree, allocated with the parser's allocator.
98 /// Result should be freed with `freeAst` when done.98 /// Result should be freed with tree.deinit() when there are
99 /// no more references to any AST nodes of the tree.
99 pub fn parse(self: &Parser) !Tree {100 pub fn parse(self: &Parser) !Tree {
100 var stack = self.initUtilityArrayList(State);101 var stack = self.initUtilityArrayList(State);
101 defer self.deinitUtilityArrayList(stack);102 defer self.deinitUtilityArrayList(stack);
std/zig/tokenizer.zig+119-14
...@@ -68,9 +68,12 @@ pub const Token = struct {...@@ -68,9 +68,12 @@ pub const Token = struct {
68 Invalid,68 Invalid,
69 Identifier,69 Identifier,
70 StringLiteral: StrLitKind,70 StringLiteral: StrLitKind,
71 StringIdentifier,
71 Eof,72 Eof,
72 Builtin,73 Builtin,
73 Bang,74 Bang,
75 Pipe,
76 PipeEqual,
74 Equal,77 Equal,
75 EqualEqual,78 EqualEqual,
76 BangEqual,79 BangEqual,
...@@ -192,6 +195,7 @@ pub const Tokenizer = struct {...@@ -192,6 +195,7 @@ pub const Tokenizer = struct {
192 StringLiteralBackslash,195 StringLiteralBackslash,
193 Equal,196 Equal,
194 Bang,197 Bang,
198 Pipe,
195 Minus,199 Minus,
196 Slash,200 Slash,
197 LineComment,201 LineComment,
...@@ -205,6 +209,7 @@ pub const Tokenizer = struct {...@@ -205,6 +209,7 @@ pub const Tokenizer = struct {
205 Ampersand,209 Ampersand,
206 Period,210 Period,
207 Period2,211 Period2,
212 SawAtSign,
208 };213 };
209214
210 pub fn next(self: &Tokenizer) Token {215 pub fn next(self: &Tokenizer) Token {
...@@ -238,8 +243,7 @@ pub const Tokenizer = struct {...@@ -238,8 +243,7 @@ pub const Tokenizer = struct {
238 result.id = Token.Id.Identifier;243 result.id = Token.Id.Identifier;
239 },244 },
240 '@' => {245 '@' => {
241 state = State.Builtin;246 state = State.SawAtSign;
242 result.id = Token.Id.Builtin;
243 },247 },
244 '=' => {248 '=' => {
245 state = State.Equal;249 state = State.Equal;
...@@ -247,6 +251,9 @@ pub const Tokenizer = struct {...@@ -247,6 +251,9 @@ pub const Tokenizer = struct {
247 '!' => {251 '!' => {
248 state = State.Bang;252 state = State.Bang;
249 },253 },
254 '|' => {
255 state = State.Pipe;
256 },
250 '(' => {257 '(' => {
251 result.id = Token.Id.LParen;258 result.id = Token.Id.LParen;
252 self.index += 1;259 self.index += 1;
...@@ -313,6 +320,20 @@ pub const Tokenizer = struct {...@@ -313,6 +320,20 @@ pub const Tokenizer = struct {
313 break;320 break;
314 },321 },
315 },322 },
323
324 State.SawAtSign => switch (c) {
325 '"' => {
326 result.id = Token.Id.StringIdentifier;
327 state = State.StringLiteral;
328 },
329 else => {
330 // reinterpret as a builtin
331 self.index -= 1;
332 state = State.Builtin;
333 result.id = Token.Id.Builtin;
334 },
335 },
336
316 State.Ampersand => switch (c) {337 State.Ampersand => switch (c) {
317 '=' => {338 '=' => {
318 result.id = Token.Id.AmpersandEqual;339 result.id = Token.Id.AmpersandEqual;
...@@ -379,6 +400,18 @@ pub const Tokenizer = struct {...@@ -379,6 +400,18 @@ pub const Tokenizer = struct {
379 },400 },
380 },401 },
381402
403 State.Pipe => switch (c) {
404 '=' => {
405 result.id = Token.Id.PipeEqual;
406 self.index += 1;
407 break;
408 },
409 else => {
410 result.id = Token.Id.Pipe;
411 break;
412 },
413 },
414
382 State.Equal => switch (c) {415 State.Equal => switch (c) {
383 '=' => {416 '=' => {
384 result.id = Token.Id.EqualEqual;417 result.id = Token.Id.EqualEqual;
...@@ -510,9 +543,62 @@ pub const Tokenizer = struct {...@@ -510,9 +543,62 @@ pub const Tokenizer = struct {
510 else => break,543 else => break,
511 },544 },
512 }545 }
513 }546 } else if (self.index == self.buffer.len) {
514 result.end = self.index;547 switch (state) {
548 State.Start,
549 State.C,
550 State.IntegerLiteral,
551 State.IntegerLiteralWithRadix,
552 State.FloatFraction,
553 State.FloatExponentNumber,
554 State.StringLiteral, // find this error later
555 State.Builtin => {},
556
557 State.Identifier => {
558 if (Token.getKeyword(self.buffer[result.start..self.index])) |id| {
559 result.id = id;
560 }
561 },
562 State.LineComment => {
563 result.id = Token.Id.Eof;
564 },
565
566 State.NumberDot,
567 State.FloatExponentUnsigned,
568 State.SawAtSign,
569 State.StringLiteralBackslash => {
570 result.id = Token.Id.Invalid;
571 },
515572
573 State.Equal => {
574 result.id = Token.Id.Equal;
575 },
576 State.Bang => {
577 result.id = Token.Id.Bang;
578 },
579 State.Minus => {
580 result.id = Token.Id.Minus;
581 },
582 State.Slash => {
583 result.id = Token.Id.Slash;
584 },
585 State.Zero => {
586 result.id = Token.Id.IntegerLiteral;
587 },
588 State.Ampersand => {
589 result.id = Token.Id.Ampersand;
590 },
591 State.Period => {
592 result.id = Token.Id.Period;
593 },
594 State.Period2 => {
595 result.id = Token.Id.Ellipsis2;
596 },
597 State.Pipe => {
598 result.id = Token.Id.Pipe;
599 },
600 }
601 }
516 if (result.id == Token.Id.Eof) {602 if (result.id == Token.Id.Eof) {
517 if (self.pending_invalid_token) |token| {603 if (self.pending_invalid_token) |token| {
518 self.pending_invalid_token = null;604 self.pending_invalid_token = null;
...@@ -520,6 +606,7 @@ pub const Tokenizer = struct {...@@ -520,6 +606,7 @@ pub const Tokenizer = struct {
520 }606 }
521 }607 }
522608
609 result.end = self.index;
523 return result;610 return result;
524 }611 }
525612
...@@ -551,7 +638,7 @@ pub const Tokenizer = struct {...@@ -551,7 +638,7 @@ pub const Tokenizer = struct {
551 } else {638 } else {
552 // check utf8-encoded character.639 // check utf8-encoded character.
553 const length = std.unicode.utf8ByteSequenceLength(c0) catch return 1;640 const length = std.unicode.utf8ByteSequenceLength(c0) catch return 1;
554 if (self.index + length >= self.buffer.len) {641 if (self.index + length > self.buffer.len) {
555 return u3(self.buffer.len - self.index);642 return u3(self.buffer.len - self.index);
556 }643 }
557 const bytes = self.buffer[self.index..self.index + length];644 const bytes = self.buffer[self.index..self.index + length];
...@@ -632,15 +719,32 @@ test "tokenizer - illegal unicode codepoints" {...@@ -632,15 +719,32 @@ test "tokenizer - illegal unicode codepoints" {
632 testTokenize("//\xe2\x80\xaa", []Token.Id{});719 testTokenize("//\xe2\x80\xaa", []Token.Id{});
633}720}
634721
722test "tokenizer - string identifier and builtin fns" {
723 testTokenize(
724 \\const @"if" = @import("std");
725 ,
726 []Token.Id{
727 Token.Id.Keyword_const,
728 Token.Id.StringIdentifier,
729 Token.Id.Equal,
730 Token.Id.Builtin,
731 Token.Id.LParen,
732 Token.Id {.StringLiteral = Token.StrLitKind.Normal},
733 Token.Id.RParen,
734 Token.Id.Semicolon,
735 }
736 );
737}
738
739test "tokenizer - pipe and then invalid" {
740 testTokenize("||=", []Token.Id{
741 Token.Id.Pipe,
742 Token.Id.PipeEqual,
743 });
744}
745
635fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {746fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {
636 // (test authors, just make this bigger if you need it)747 var tokenizer = Tokenizer.init(source);
637 var padded_source: [0x100]u8 = undefined;
638 std.mem.copy(u8, padded_source[0..source.len], source);
639 padded_source[source.len + 0] = '\n';
640 padded_source[source.len + 1] = '\n';
641 padded_source[source.len + 2] = '\n';
642
643 var tokenizer = Tokenizer.init(padded_source[0..source.len + 3]);
644 for (expected_tokens) |expected_token_id| {748 for (expected_tokens) |expected_token_id| {
645 const token = tokenizer.next();749 const token = tokenizer.next();
646 std.debug.assert(@TagType(Token.Id)(token.id) == @TagType(Token.Id)(expected_token_id));750 std.debug.assert(@TagType(Token.Id)(token.id) == @TagType(Token.Id)(expected_token_id));
...@@ -651,5 +755,6 @@ fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {...@@ -651,5 +755,6 @@ fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {
651 else => {},755 else => {},
652 }756 }
653 }757 }
654 std.debug.assert(tokenizer.next().id == Token.Id.Eof);758 const last_token = tokenizer.next();
759 std.debug.assert(last_token.id == Token.Id.Eof);
655}760}