0 diff --git a/.gitignore b/.gitignore
1 index 9a883edfd..5f852d930 100644
2 --- a/.gitignore
3 +++ b/.gitignore
4 @@ -12,5 +12,6 @@ all_spec
5  /tmp
6  /doc/
7  /src/llvm/ext/llvm_ext.o
8 +/src/llvm/ext/llvm_ext.dwo
9  /src/ext/*.o
10  /src/ext/libcrystal.a
11 diff --git a/Makefile b/Makefile
12 index a5dc0d7e3..14a21bb86 100644
13 --- a/Makefile
14 +++ b/Makefile
15 @@ -37,8 +37,6 @@ LLVM_CONFIG_FINDER := \
16      (command -v llvm-config > /dev/null && (case "$(llvm-config --version)" in 3.9*) command -v llvm-config;; *) false;; esac)) || \
17    command -v llvm-config-3.8 || command -v llvm-config38 || \
18      (command -v llvm-config > /dev/null && (case "$(llvm-config --version)" in 3.8*) command -v llvm-config;; *) false;; esac)) || \
19 -  command -v llvm-config-3.6 || command -v llvm-config36 || \
20 -  command -v llvm-config-3.5 || command -v llvm-config35 || \
21    command -v llvm-config
22  LLVM_CONFIG := $(shell $(LLVM_CONFIG_FINDER))
23  LLVM_EXT_DIR = src/llvm/ext
24 diff --git a/src/compiler/crystal/compiler.cr b/src/compiler/crystal/compiler.cr
25 index a2bed9a95..afc7976e3 100644
26 --- a/src/compiler/crystal/compiler.cr
27 +++ b/src/compiler/crystal/compiler.cr
28 @@ -447,9 +447,6 @@ module Crystal
29 
30      protected def optimize(llvm_mod)
31        fun_pass_manager = llvm_mod.new_function_pass_manager
32 -      {% if LibLLVM::IS_35 || LibLLVM::IS_36 %}
33 -        fun_pass_manager.add_target_data target_machine.data_layout
34 -      {% end %}
35        pass_manager_builder.populate fun_pass_manager
36        fun_pass_manager.run llvm_mod
37        module_pass_manager.run llvm_mod
38 @@ -460,9 +457,6 @@ module Crystal
39      private def module_pass_manager
40        @module_pass_manager ||= begin
41          mod_pass_manager = LLVM::ModulePassManager.new
42 -        {% if LibLLVM::IS_35 || LibLLVM::IS_36 %}
43 -          mod_pass_manager.add_target_data target_machine.data_layout
44 -        {% end %}
45          pass_manager_builder.populate mod_pass_manager
46          mod_pass_manager
47        end
48 @@ -554,54 +548,29 @@ module Crystal
49          can_reuse_previous_compilation =
50            !compiler.emit && !@bc_flags_changed && File.exists?(bc_name) && File.exists?(object_name)
51 
52 -        {% if LibLLVM::IS_35 %}
53 -          # In LLVM 3.5 we can't write a bitcode to memory,
54 -          # so instead we write it to another file
55 -          bc_name_new = self.bc_name_new
56 -          llvm_mod.write_bitcode_to_file(bc_name_new)
57 -
58 -          if can_reuse_previous_compilation
59 -            if FileUtils.cmp(bc_name, bc_name_new)
60 -              # If the user cancelled a previous compilation it might be that
61 -              # the .o file is empty
62 -              if File.size(object_name) > 0
63 -                File.delete bc_name_new
64 -                must_compile = false
65 -              end
66 -            end
67 -          end
68 +        memory_buffer = llvm_mod.write_bitcode_to_memory_buffer
69 
70 -          if must_compile
71 -            # Create/overwrite the .bc file (for next compilations)
72 -            File.rename(bc_name_new, bc_name)
73 -            compiler.optimize llvm_mod if compiler.release?
74 -            compiler.target_machine.emit_obj_to_file llvm_mod, object_name
75 -          end
76 -        {% else %}
77 -          memory_buffer = llvm_mod.write_bitcode_to_memory_buffer
78 -
79 -          if can_reuse_previous_compilation
80 -            memory_io = IO::Memory.new(memory_buffer.to_slice)
81 -            changed = File.open(bc_name) { |bc_file| !FileUtils.cmp(bc_file, memory_io) }
82 -
83 -            # If the user cancelled a previous compilation
84 -            # it might be that the .o file is empty
85 -            if !changed && File.size(object_name) > 0
86 -              must_compile = false
87 -              memory_buffer.dispose
88 -              memory_buffer = nil
89 -            else
90 -              # We need to compile, so we'll write the memory buffer to file
91 -            end
92 -          end
93 +        if can_reuse_previous_compilation
94 +          memory_io = IO::Memory.new(memory_buffer.to_slice)
95 +          changed = File.open(bc_name) { |bc_file| !FileUtils.cmp(bc_file, memory_io) }
96 
97 -          # If there's a memory buffer, it means we must create a .o from it
98 -          if memory_buffer
99 -            # Create the .bc file (for next compilations)
100 -            File.write(bc_name, memory_buffer.to_slice)
101 +          # If the user cancelled a previous compilation
102 +          # it might be that the .o file is empty
103 +          if !changed && File.size(object_name) > 0
104 +            must_compile = false
105              memory_buffer.dispose
106 +            memory_buffer = nil
107 +          else
108 +            # We need to compile, so we'll write the memory buffer to file
109            end
110 -        {% end %}
111 +        end
112 +
113 +        # If there's a memory buffer, it means we must create a .o from it
114 +        if memory_buffer
115 +          # Create the .bc file (for next compilations)
116 +          File.write(bc_name, memory_buffer.to_slice)
117 +          memory_buffer.dispose
118 +        end
119 
120          if must_compile
121            compiler.optimize llvm_mod if compiler.release?
122 diff --git a/src/llvm.cr b/src/llvm.cr
123 index 44a03c272..f9b31cf4b 100644
124 --- a/src/llvm.cr
125 +++ b/src/llvm.cr
126 @@ -94,11 +94,5 @@ module LLVM
127      string
128    end
129 
130 -  {% if LibLLVM::IS_35 %}
131 -    DEBUG_METADATA_VERSION = 1
132 -  {% elsif LibLLVM::IS_36 %}
133 -    DEBUG_METADATA_VERSION = 2
134 -  {% else %}
135 -    DEBUG_METADATA_VERSION = 3
136 -  {% end %}
137 +  DEBUG_METADATA_VERSION = 3
138  end
139 diff --git a/src/llvm/context.cr b/src/llvm/context.cr
140 index 8485eedf1..7d66a4365 100644
141 --- a/src/llvm/context.cr
142 +++ b/src/llvm/context.cr
143 @@ -9,9 +9,9 @@ class LLVM::Context
144    end
145 
146    def new_module(name : String) : Module
147 -    {% if LibLLVM::IS_38 || LibLLVM::IS_36 || LibLLVM::IS_35 %}
148 +    {% if LibLLVM::IS_38 %}
149        Module.new(LibLLVM.module_create_with_name_in_context(name, self), name, self)
150 -    {% else %}
151 +    {% else %} # LLVM >= 3.9
152        Module.new(LibLLVM.module_create_with_name_in_context(name, self), self)
153      {% end %}
154    end
155 @@ -104,9 +104,9 @@ class LLVM::Context
156      if ret != 0 && msg
157        raise LLVM.string_and_dispose(msg)
158      end
159 -    {% if LibLLVM::IS_38 || LibLLVM::IS_36 || LibLLVM::IS_35 %}
160 +    {% if LibLLVM::IS_38 %}
161        Module.new(mod, "unknown", self)
162 -    {% else %}
163 +    {% else %} # LLVM >= 3.9
164        Module.new(mod, self)
165      {% end %}
166    end
167 diff --git a/src/llvm/di_builder.cr b/src/llvm/di_builder.cr
168 index b8c0fd628..79571d2c0 100644
169 --- a/src/llvm/di_builder.cr
170 +++ b/src/llvm/di_builder.cr
171 @@ -31,16 +31,8 @@ struct LLVM::DIBuilder
172 
173    def create_function(scope, name, linkage_name, file, line, composite_type, is_local_to_unit, is_definition,
174                        scope_line, flags, is_optimized, func)
175 -    {% if LibLLVM::IS_36 || LibLLVM::IS_35 %}
176 -      LibLLVMExt.di_builder_create_function(self, scope, name, linkage_name, file, line, composite_type,
177 -                                            is_local_to_unit ? 1 : 0,
178 -                                            is_definition ? 1 : 0,
179 -                                            scope_line, flags,
180 -                                            is_optimized ? 1 : 0, func)
181 -    {% else %}
182 -      LibLLVMExt.di_builder_create_function(self, scope, name, linkage_name, file, line, composite_type,
183 -                                            is_local_to_unit, is_definition, scope_line, flags, is_optimized, func)
184 -    {% end %}
185 +    LibLLVMExt.di_builder_create_function(self, scope, name, linkage_name, file, line, composite_type,
186 +      is_local_to_unit, is_definition, scope_line, flags, is_optimized, func)
187    end
188 
189    def create_auto_variable(scope, name, file, line, type, align_in_bits)
190 @@ -87,19 +79,11 @@ struct LLVM::DIBuilder
191    end
192 
193    def create_replaceable_composite_type(scope, name, file, line, context : Context)
194 -    {% if LibLLVM::IS_35 || LibLLVM::IS_36 %}
195 -      LibLLVMExt.temporary_md_node(context, nil, 0).as(LibLLVMExt::Metadata)
196 -    {% else %}
197 -      LibLLVMExt.di_builder_create_replaceable_composite_type(self, scope, name, file, line)
198 -    {% end %}
199 +    LibLLVMExt.di_builder_create_replaceable_composite_type(self, scope, name, file, line)
200    end
201 
202    def replace_temporary(from, to)
203 -    {% if LibLLVM::IS_35 || LibLLVM::IS_36 %}
204 -      LibLLVMExt.metadata_replace_all_uses_with(from, to)
205 -    {% else %}
206 -      LibLLVMExt.di_builder_replace_temporary(self, from, to)
207 -    {% end %}
208 +    LibLLVMExt.di_builder_replace_temporary(self, from, to)
209    end
210 
211    def end
212 diff --git a/src/llvm/ext/llvm_ext.cc b/src/llvm/ext/llvm_ext.cc
213 index d13446160..3dbdd4220 100644
214 --- a/src/llvm/ext/llvm_ext.cc
215 +++ b/src/llvm/ext/llvm_ext.cc
216 @@ -18,35 +18,22 @@ using namespace llvm;
217  #define LLVM_VERSION_LE(major, minor) \
218    (LLVM_VERSION_MAJOR < (major) || LLVM_VERSION_MAJOR == (major) && LLVM_VERSION_MINOR <= (minor))
219 
220 +#if LLVM_VERSION_LE(4, 0)
221  typedef struct LLVMOpaqueDIBuilder *LLVMDIBuilderRef;
222  DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIBuilder, LLVMDIBuilderRef)
223 
224 -#if LLVM_VERSION_EQ(3, 5)
225 -typedef LLVMValueRef LLVMMetadataRef;
226 -typedef Value Metadata;
227 -#define DIBuilderRef LLVMDIBuilderRef
228 -
229 -#else /* LLVM != 3.5 */
230  typedef struct LLVMOpaqueMetadata *LLVMMetadataRef;
231  DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMMetadataRef)
232  inline Metadata **unwrap(LLVMMetadataRef *Vals) {
233    return reinterpret_cast(Vals);
234  }
235 -#endif /* LLVM == 3.5 */
236 -
237 -#if LLVM_VERSION_LE(3, 6)
238 -template  T unwrapDIptr(LLVMMetadataRef v) {
239 -  return v ? T(unwrap(v)) : T();
240 -}
241 -#define DIBuilderRef LLVMDIBuilderRef
242 +#endif
243 
244 -#else /* LLVM > 3.6 */
245  typedef DIBuilder *DIBuilderRef;
246  #define DIArray DINodeArray
247  template  T *unwrapDIptr(LLVMMetadataRef v) {
248    return (T *)(v ? unwrap(v) : NULL);
249  }
250 -#endif /* LLVM <= 3.6 */
251 
252  #if LLVM_VERSION_LE(3, 6)
253  #define OperandBundleDef void
254 @@ -66,13 +53,7 @@ void LLVMDIBuilderFinalize(LLVMDIBuilderRef dref) { unwrap(dref)->finalize(); }
255 
256  LLVMMetadataRef LLVMDIBuilderCreateFile(DIBuilderRef Dref, const char *File,
257                                          const char *Dir) {
258 -#if LLVM_VERSION_LE(3, 6)
259 -  DIBuilder *D = unwrap(Dref);
260 -  DIFile F = D->createFile(File, Dir);
261 -  return wrap(F);
262 -#else
263    return wrap(Dref->createFile(File, Dir));
264 -#endif
265  }
266 
267  LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(DIBuilderRef Dref, unsigned Lang,
268 @@ -82,20 +63,13 @@ LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(DIBuilderRef Dref, unsigned Lang,
269                                                 int Optimized,
270                                                 const char *Flags,
271                                                 unsigned RuntimeVersion) {
272 -#if LLVM_VERSION_LE(3, 6)
273 -  DIBuilder *D = unwrap(Dref);
274 -  DICompileUnit CU = D->createCompileUnit(Lang, File, Dir, Producer, Optimized,
275 -                                          Flags, RuntimeVersion);
276 -  return wrap(CU);
277 -#else
278 -# if LLVM_VERSION_LE(3, 9)
279 +#if LLVM_VERSION_LE(3, 9)
280    return wrap(Dref->createCompileUnit(Lang, File, Dir, Producer, Optimized,
281                                        Flags, RuntimeVersion));
282 -# else
283 +#else
284    DIFile *F = Dref->createFile(File, Dir);
285    return wrap(Dref->createCompileUnit(Lang, F, Producer, Optimized,
286                                        Flags, RuntimeVersion));
287 -# endif
288  #endif
289  }
290 
291 @@ -111,19 +85,11 @@ LLVMMetadataRef LLVMDIBuilderCreateFunction(
292  #endif
293      bool IsOptimized,
294      LLVMValueRef Func) {
295 -#if LLVM_VERSION_LE(3, 6)
296 -  DIBuilder *D = unwrap(Dref);
297 -  DISubprogram Sub = D->createFunction(
298 -      unwrapDI(Scope), Name, LinkageName, unwrapDI(File),
299 -      Line, unwrapDI(CompositeType), IsLocalToUnit,
300 -      IsDefinition, ScopeLine, Flags, IsOptimized, unwrap(Func));
301 -#else
302    DISubprogram *Sub = Dref->createFunction(
303        unwrapDI(Scope), Name, LinkageName, unwrapDI(File), Line,
304        unwrapDI(CompositeType), IsLocalToUnit, IsDefinition,
305        ScopeLine, Flags, IsOptimized);
306    unwrap(Func)->setSubprogram(Sub);
307 -#endif
308    return wrap(Sub);
309  }
310 
311 @@ -132,18 +98,8 @@ LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(DIBuilderRef Dref,
312                                                  LLVMMetadataRef File,
313                                                  unsigned Line,
314                                                  unsigned Column) {
315 -#if LLVM_VERSION_LE(3, 6)
316 -  DIBuilder *D = unwrap(Dref);
317 -# if LLVM_VERSION_EQ(3, 5)
318 -  DILexicalBlock LB = D->createLexicalBlock(unwrapDI(Scope), unwrapDI(File), Line, Column, 0);
319 -# else /* LLVM <= 3.6 && LLVM != 3.5 */
320 -  DILexicalBlock LB = D->createLexicalBlock(unwrapDI(Scope), unwrapDI(File), Line, Column);
321 -# endif
322 -  return wrap(LB);
323 -#else /* LLVM > 3.6 */
324    return wrap(Dref->createLexicalBlock(unwrapDI(Scope),
325                                         unwrapDI(File), Line, Column));
326 -#endif /* LLVM <= 3.6 */
327  }
328 
329  LLVMMetadataRef LLVMDIBuilderCreateBasicType(DIBuilderRef Dref,
330 @@ -151,71 +107,34 @@ LLVMMetadataRef LLVMDIBuilderCreateBasicType(DIBuilderRef Dref,
331                                               uint64_t SizeInBits,
332                                               uint64_t AlignInBits,
333                                               unsigned Encoding) {
334 -#if LLVM_VERSION_LE(3, 6)
335 -  DIBuilder *D = unwrap(Dref);
336 -  DIBasicType T = D->createBasicType(Name, SizeInBits, AlignInBits, Encoding);
337 -  return wrap(T);
338 -#else
339 -# if LLVM_VERSION_LE(3, 9)
340 +#if LLVM_VERSION_LE(3, 9)
341    return wrap(Dref->createBasicType(Name, SizeInBits, AlignInBits, Encoding));
342 -# else
343 +#else
344    return wrap(Dref->createBasicType(Name, SizeInBits, Encoding));
345 -# endif
346  #endif
347  }
348 
349  LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(DIBuilderRef Dref,
350                                                    LLVMMetadataRef *Data,
351                                                    unsigned Length) {
352 -#if LLVM_VERSION_LE(3, 6)
353 -  DIBuilder *D = unwrap(Dref);
354 -# if LLVM_VERSION_EQ(3, 5)
355 -  Value **DataValue = unwrap(Data);
356 -  ArrayRef Elements(DataValue, Length);
357 -  DIArray A = D->getOrCreateArray(Elements);
358 -# else /* LLVM <= 3.6 && LLVM != 3.5 */
359 -  Metadata **DataValue = unwrap(Data);
360 -  ArrayRef Elements(DataValue, Length);
361 -  DITypeArray A = D->getOrCreateTypeArray(Elements);
362 -# endif
363 -  return wrap(A);
364 -#else /* LLVM > 3.6 */
365    Metadata **DataValue = unwrap(Data);
366    return wrap(
367        Dref->getOrCreateTypeArray(ArrayRef(DataValue, Length))
368            .get());
369 -#endif /* LLVM <= 3.6 */
370  }
371 
372  LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(DIBuilderRef Dref,
373                                                LLVMMetadataRef *Data,
374                                                unsigned Length) {
375 -#if LLVM_VERSION_LE(3, 6)
376 -  DIBuilder *D = unwrap(Dref);
377 -  ArrayRef elements(unwrap(Data), Length);
378 -  DIArray a = D->getOrCreateArray(elements);
379 -
380 -  return wrap(a);
381 -#else
382    Metadata **DataValue = unwrap(Data);
383    return wrap(
384        Dref->getOrCreateArray(ArrayRef(DataValue, Length)).get());
385 -#endif
386  }
387 
388  LLVMMetadataRef
389  LLVMDIBuilderCreateSubroutineType(DIBuilderRef Dref, LLVMMetadataRef File,
390                                    LLVMMetadataRef ParameterTypes) {
391 -#if LLVM_VERSION_LE(3, 6)
392 -  DIBuilder *D = unwrap(Dref);
393 -# if LLVM_VERSION_EQ(3, 5)
394 -  DICompositeType CT = D->createSubroutineType(unwrapDI(File), unwrapDI(ParameterTypes));
395 -# else /* LLVM <= 3.6 && LLVM != 3.5 */
396 -  DICompositeType CT = D->createSubroutineType(unwrapDI(File), unwrapDI(ParameterTypes));
397 -# endif
398 -#else /* LLVM > 3.6 */
399    DISubroutineType *CT = Dref->createSubroutineType(DITypeRefArray(unwrap(ParameterTypes)));
400 -#endif /* LLVM <= 3.6 */
401    return wrap(CT);
402  }
403 
404 @@ -229,21 +148,14 @@ LLVMMetadataRef LLVMDIBuilderCreateAutoVariable(
405      DINode::DIFlags Flags,
406  #endif
407      uint32_t AlignInBits) {
408 -#if LLVM_VERSION_LE(3, 6)
409 -  DIBuilder *D = unwrap(Dref);
410 -  DIVariable V = D->createLocalVariable(
411 -      llvm::dwarf::DW_TAG_auto_variable, unwrapDI(Scope), Name, unwrapDI(File), Line,
412 -      unwrapDI(Ty), AlwaysPreserve, Flags, 0);
413 -#else
414 -# if LLVM_VERSION_LE(3, 9)
415 +#if LLVM_VERSION_LE(3, 9)
416    DILocalVariable *V = Dref->createAutoVariable(
417        unwrapDI(Scope), Name, unwrapDI(File), Line,
418        unwrapDI(Ty), AlwaysPreserve, Flags);
419 -# else
420 +#else
421    DILocalVariable *V = Dref->createAutoVariable(
422        unwrapDI(Scope), Name, unwrapDI(File), Line,
423        unwrapDI(Ty), AlwaysPreserve, Flags, AlignInBits);
424 -# endif
425  #endif
426    return wrap(V);
427  }
428 @@ -258,18 +170,10 @@ LLVMMetadataRef LLVMDIBuilderCreateParameterVariable(
429      DINode::DIFlags Flags
430  #endif
431      ) {
432 -#if LLVM_VERSION_LE(3, 6)
433 -  DIBuilder *D = unwrap(Dref);
434 -  DIVariable V = D->createLocalVariable(
435 -       llvm::dwarf::DW_TAG_arg_variable, unwrapDI(Scope), Name, unwrapDI(File), Line,
436 -       unwrapDI(Ty), AlwaysPreserve, Flags, ArgNo);
437 -  return wrap(V);
438 -#else
439    DILocalVariable *V = Dref->createParameterVariable
440      (unwrapDI(Scope), Name, ArgNo, unwrapDI(File), Line,
441       unwrapDI(Ty), AlwaysPreserve, Flags);
442    return wrap(V);
443 -#endif
444  }
445 
446  LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(DIBuilderRef Dref,
447 @@ -278,46 +182,17 @@ LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(DIBuilderRef Dref,
448                                               LLVMMetadataRef Expr,
449                                               LLVMValueRef DL,
450                                               LLVMBasicBlockRef Block) {
451 -#if LLVM_VERSION_EQ(3, 5)
452 -  DIBuilder *D = unwrap(Dref);
453 -  Instruction *Instr =
454 -    D->insertDeclare(unwrap(Storage), unwrapDI(VarInfo),
455 -                     unwrap(Block));
456 -  Instr->setDebugLoc(DebugLoc::getFromDILocation(cast(DL)));
457 -#endif
458 -
459 -#if LLVM_VERSION_EQ(3, 6)
460 -  DIBuilder *D = unwrap(Dref);
461 -  Instruction *Instr =
462 -    D->insertDeclare(unwrap(Storage), unwrapDI(VarInfo),
463 -                     unwrapDI(Expr), unwrap(Block));
464 -  Instr->setDebugLoc(DebugLoc::getFromDILocation(cast(unwrap(DL)->getMetadata())));
465 -#endif
466 -
467 -#if LLVM_VERSION_GE(3, 7)
468    Instruction *Instr =
469      Dref->insertDeclare(unwrap(Storage), unwrap(VarInfo),
470                          unwrapDI(Expr),
471                          DebugLoc(cast(unwrap(DL)->getMetadata())),
472                          unwrap(Block));
473 -#endif
474 -
475    return wrap(Instr);
476  }
477 
478  LLVMMetadataRef LLVMDIBuilderCreateExpression(DIBuilderRef Dref, int64_t *Addr,
479                                                size_t Length) {
480 -#if LLVM_VERSION_LE(3, 6)
481 -# if LLVM_VERSION_EQ(3, 5)
482 -  return nullptr;
483 -# else /* LLVM <= 3.6 && LLVM != 3.5 */
484 -  DIBuilder *D = unwrap(Dref);
485 -  DIExpression Expr = D->createExpression(ArrayRef(Addr, Length));
486 -  return wrap(Expr);
487 -# endif
488 -#else /* LLVM > 3.6 */
489    return wrap(Dref->createExpression(ArrayRef(Addr, Length)));
490 -#endif
491  }
492 
493  LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
494 @@ -325,30 +200,16 @@ LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
495      LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
496      uint64_t AlignInBits, LLVMMetadataRef Elements,
497      LLVMMetadataRef UnderlyingType) {
498 -#if LLVM_VERSION_LE(3, 6)
499 -  DIBuilder *D = unwrap(Dref);
500 -  DICompositeType enumType = D->createEnumerationType(
501 -      unwrapDI(Scope), Name, unwrapDI(File), LineNumber,
502 -      SizeInBits, AlignInBits, unwrapDI(Elements),
503 -      unwrapDI(UnderlyingType));
504 -#else
505    DICompositeType *enumType = Dref->createEnumerationType(
506        unwrapDI(Scope), Name, unwrapDI(File), LineNumber,
507        SizeInBits, AlignInBits, DINodeArray(unwrapDI(Elements)),
508        unwrapDI(UnderlyingType));
509 -#endif
510    return wrap(enumType);
511  }
512 
513  LLVMMetadataRef LLVMDIBuilderCreateEnumerator(DIBuilderRef Dref,
514                                                const char *Name, int64_t Value) {
515 -#if LLVM_VERSION_LE(3, 6)
516 -  DIBuilder *D = unwrap(Dref);
517 -  DIEnumerator e = D->createEnumerator(Name, Value);
518 -  return wrap(e);
519 -#else
520    DIEnumerator *e = Dref->createEnumerator(Name, Value);
521 -#endif
522    return wrap(e);
523  }
524 
525 @@ -367,22 +228,13 @@ LLVMDIBuilderCreateStructType(DIBuilderRef Dref,
526  #endif
527                                LLVMMetadataRef DerivedFrom,
528                                LLVMMetadataRef Elements) {
529 -#if LLVM_VERSION_LE(3, 6)
530 -  DIBuilder *D = unwrap(Dref);
531 -  DICompositeType CT = D->createStructType(
532 -      unwrapDI(Scope), Name, unwrapDI(File), Line,
533 -      SizeInBits, AlignInBits, Flags, unwrapDI(DerivedFrom),
534 -      unwrapDI(Elements));
535 -#else
536    DICompositeType *CT = Dref->createStructType(
537        unwrapDI(Scope), Name, unwrapDI(File), Line,
538        SizeInBits, AlignInBits, Flags, unwrapDI(DerivedFrom),
539        DINodeArray(unwrapDI(Elements)));
540 -#endif
541    return wrap(CT);
542  }
543 
544 -#if LLVM_VERSION_GE(3, 8)
545  LLVMMetadataRef
546  LLVMDIBuilderCreateReplaceableCompositeType(DIBuilderRef Dref,
547                                              LLVMMetadataRef Scope,
548 @@ -409,7 +261,6 @@ LLVMDIBuilderReplaceTemporary(DIBuilderRef Dref,
549    llvm::TempMDNode fwd_decl(Node);
550    Dref->replaceTemporary(std::move(fwd_decl), Type);
551  }
552 -#endif
553 
554  LLVMMetadataRef
555  LLVMDIBuilderCreateMemberType(DIBuilderRef Dref, LLVMMetadataRef Scope,
556 @@ -422,16 +273,9 @@ LLVMDIBuilderCreateMemberType(DIBuilderRef Dref, LLVMMetadataRef Scope,
557                                DINode::DIFlags Flags,
558  #endif
559                                LLVMMetadataRef Ty) {
560 -#if LLVM_VERSION_LE(3, 6)
561 -  DIBuilder *D = unwrap(Dref);
562 -  DIDerivedType DT = D->createMemberType(
563 -      unwrapDI(Scope), Name, unwrapDI(File), Line,
564 -      SizeInBits, AlignInBits, OffsetInBits, Flags, unwrapDI(Ty));
565 -#else
566    DIDerivedType *DT = Dref->createMemberType(
567        unwrapDI(Scope), Name, unwrapDI(File), Line,
568        SizeInBits, AlignInBits, OffsetInBits, Flags, unwrapDI(Ty));
569 -#endif
570    return wrap(DT);
571  }
572 
573 @@ -440,39 +284,24 @@ LLVMMetadataRef LLVMDIBuilderCreatePointerType(DIBuilderRef Dref,
574                                                 uint64_t SizeInBits,
575                                                 uint64_t AlignInBits,
576                                                 const char *Name) {
577 -#if LLVM_VERSION_LE(3, 6)
578 -  DIBuilder *D = unwrap(Dref);
579 -  DIDerivedType T = D->createPointerType(unwrapDI(PointeeType),
580 -                                         SizeInBits, AlignInBits, Name);
581 -#else
582    DIDerivedType *T = Dref->createPointerType(unwrapDI(PointeeType),
583 -                                             SizeInBits, AlignInBits, Name);
584 +                                             SizeInBits, AlignInBits,
585 +#if LLVM_VERSION_GE(5, 0)
586 +                                             None,
587  #endif
588 +                                             Name);
589    return wrap(T);
590  }
591 
592  LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef C, LLVMMetadataRef *MDs,
593                                      unsigned Count) {
594 -#if LLVM_VERSION_LE(3, 6)
595 -  return wrap(MDNode::getTemporary(*unwrap(C),
596 -                                   ArrayRef(unwrap(MDs), Count)));
597 -#else
598    return wrap(MDTuple::getTemporary(*unwrap(C),
599                                      ArrayRef(unwrap(MDs), Count))
600                    .release());
601 -#endif
602  }
603 
604  void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef MD, LLVMMetadataRef New) {
605 -#if LLVM_VERSION_LE(3, 6)
606 -# if LLVM_VERSION_EQ(3, 5)
607    auto *Node = unwrap(MD);
608 -# else /* LLVM <= 3.6 && LLVM != 3.5 */
609 -  auto *Node = unwrap(MD);
610 -# endif
611 -#else /* LLVM > 3.6 */
612 -  auto *Node = unwrap(MD);
613 -#endif
614    Node->replaceAllUsesWith(unwrap(New));
615    MDNode::deleteTemporary(Node);
616  }
617 diff --git a/src/llvm/function_pass_manager.cr b/src/llvm/function_pass_manager.cr
618 index 979cb9c97..834d72a20 100644
619 --- a/src/llvm/function_pass_manager.cr
620 +++ b/src/llvm/function_pass_manager.cr
621 @@ -2,12 +2,6 @@ class LLVM::FunctionPassManager
622    def initialize(@unwrap : LibLLVM::PassManagerRef)
623    end
624 
625 -  {% if LibLLVM::IS_35 || LibLLVM::IS_36 %}
626 -    def add_target_data(target_data)
627 -      LibLLVM.add_target_data target_data, self
628 -    end
629 -  {% end %}
630 -
631    def run(mod : Module)
632      changed = false
633      run do |runner|
634 diff --git a/src/llvm/lib_llvm.cr b/src/llvm/lib_llvm.cr
635 index e2c7a9445..5a0b67cdd 100644
636 --- a/src/llvm/lib_llvm.cr
637 +++ b/src/llvm/lib_llvm.cr
638 @@ -6,8 +6,6 @@ lib LibLLVM
639                     (command -v llvm-config > /dev/null && (case "$(llvm-config --version)" in 3.9*) command -v llvm-config;; *) false;; esac)) || \
640                     command -v llvm-config-3.8 || command -v llvm-config38 || \
641                     (command -v llvm-config > /dev/null && (case "$(llvm-config --version)" in 3.8*) command -v llvm-config;; *) false;; esac)) || \
642 -                   command -v llvm-config-3.6 || command -v llvm-config36 || \
643 -                   command -v llvm-config-3.5 || command -v llvm-config35 || \
644                     command -v llvm-config
645                    `.chomp.stringify
646                  }}
647 @@ -32,8 +30,6 @@ end
648      IS_40 = {{LibLLVM::VERSION.starts_with?("4.0")}}
649      IS_39 = {{LibLLVM::VERSION.starts_with?("3.9")}}
650      IS_38 = {{LibLLVM::VERSION.starts_with?("3.8")}}
651 -    IS_36 = {{LibLLVM::VERSION.starts_with?("3.6")}}
652 -    IS_35 = {{LibLLVM::VERSION.starts_with?("3.5")}}
653    end
654  {% end %}
655 
656 @@ -283,9 +279,7 @@ lib LibLLVM
657    fun set_alignment = LLVMSetAlignment(value : ValueRef, bytes : UInt32)
658    fun get_return_type = LLVMGetReturnType(TypeRef) : TypeRef
659 
660 -  {% unless LibLLVM::IS_35 %}
661 -    fun write_bitcode_to_memory_buffer = LLVMWriteBitcodeToMemoryBuffer(mod : ModuleRef) : MemoryBufferRef
662 -  {% end %}
663 +  fun write_bitcode_to_memory_buffer = LLVMWriteBitcodeToMemoryBuffer(mod : ModuleRef) : MemoryBufferRef
664 
665    fun dispose_memory_buffer = LLVMDisposeMemoryBuffer(buf : MemoryBufferRef) : Void
666    fun get_buffer_start = LLVMGetBufferStart(buf : MemoryBufferRef) : UInt8*
667 @@ -293,26 +287,22 @@ lib LibLLVM
668 
669    fun write_bitcode_to_fd = LLVMWriteBitcodeToFD(mod : ModuleRef, fd : LibC::Int, should_close : LibC::Int, unbuffered : LibC::Int) : LibC::Int
670 
671 -  {% if LibLLVM::IS_36 || LibLLVM::IS_35 %}
672 -    fun add_target_data = LLVMAddTargetData(td : TargetDataRef, pm : PassManagerRef)
673 -  {% end %}
674 -
675 -  {% if LibLLVM::IS_38 || LibLLVM::IS_36 || LibLLVM::IS_35 %}
676 +  {% if LibLLVM::IS_38 %}
677      fun copy_string_rep_of_target_data = LLVMCopyStringRepOfTargetData(data : TargetDataRef) : UInt8*
678      fun get_target_machine_data = LLVMGetTargetMachineData(t : TargetMachineRef) : TargetDataRef
679      fun set_data_layout = LLVMSetDataLayout(mod : ModuleRef, data : UInt8*)
680 -  {% else %}
681 +  {% else %} # LLVM >= 3.9
682      fun create_target_data_layout = LLVMCreateTargetDataLayout(t : TargetMachineRef) : TargetDataRef
683      fun set_module_data_layout = LLVMSetModuleDataLayout(mod : ModuleRef, data : TargetDataRef)
684    {% end %}
685 
686 -  {% if LibLLVM::IS_38 || LibLLVM::IS_36 || LibLLVM::IS_35 %}
687 +  {% if LibLLVM::IS_38 %}
688      fun add_attribute = LLVMAddAttribute(arg : ValueRef, attr : LLVM::Attribute)
689      fun add_instr_attribute = LLVMAddInstrAttribute(instr : ValueRef, index : UInt32, attr : LLVM::Attribute)
690      fun add_function_attr = LLVMAddFunctionAttr(fn : ValueRef, pa : LLVM::Attribute)
691      fun get_function_attr = LLVMGetFunctionAttr(fn : ValueRef) : LLVM::Attribute
692      fun get_attribute = LLVMGetAttribute(arg : ValueRef) : LLVM::Attribute
693 -  {% else %}
694 +  {% else %} # LLVM >= 3.9
695      type AttributeRef = Void*
696      alias AttributeIndex = UInt
697 
698 diff --git a/src/llvm/lib_llvm_ext.cr b/src/llvm/lib_llvm_ext.cr
699 index 84c65cccb..953567eb8 100644
700 --- a/src/llvm/lib_llvm_ext.cr
701 +++ b/src/llvm/lib_llvm_ext.cr
702 @@ -13,19 +13,11 @@ lib LibLLVMExt
703    fun create_di_builder = LLVMNewDIBuilder(LibLLVM::ModuleRef) : DIBuilder
704    fun di_builder_finalize = LLVMDIBuilderFinalize(DIBuilder)
705 
706 -  {% if LibLLVM::IS_36 || LibLLVM::IS_35 %}
707 -    fun di_builder_create_function = LLVMDIBuilderCreateFunction(
708 -                                                                 builder : DIBuilder, scope : Metadata, name : Char*,
709 -                                                                 linkage_name : Char*, file : Metadata, line : UInt,
710 -                                                                 composite_type : Metadata, is_local_to_unit : Int, is_definition : Int,
711 -                                                                 scope_line : UInt, flags : LLVM::DIFlags, is_optimized : Int, func : LibLLVM::ValueRef) : Metadata
712 -  {% else %}
713 -    fun di_builder_create_function = LLVMDIBuilderCreateFunction(
714 -                                                                 builder : DIBuilder, scope : Metadata, name : Char*,
715 -                                                                 linkage_name : Char*, file : Metadata, line : UInt,
716 -                                                                 composite_type : Metadata, is_local_to_unit : Bool, is_definition : Bool,
717 -                                                                 scope_line : UInt, flags : LLVM::DIFlags, is_optimized : Bool, func : LibLLVM::ValueRef) : Metadata
718 -  {% end %}
719 +  fun di_builder_create_function = LLVMDIBuilderCreateFunction(
720 +                                                               builder : DIBuilder, scope : Metadata, name : Char*,
721 +                                                               linkage_name : Char*, file : Metadata, line : UInt,
722 +                                                               composite_type : Metadata, is_local_to_unit : Bool, is_definition : Bool,
723 +                                                               scope_line : UInt, flags : LLVM::DIFlags, is_optimized : Bool, func : LibLLVM::ValueRef) : Metadata
724 
725    fun di_builder_create_file = LLVMDIBuilderCreateFile(builder : DIBuilder, file : Char*, dir : Char*) : Metadata
726    fun di_builder_create_compile_unit = LLVMDIBuilderCreateCompileUnit(builder : DIBuilder,
727 @@ -94,17 +86,12 @@ lib LibLLVMExt
728                                                                        align_in_bits : UInt64,
729                                                                        name : Char*) : Metadata
730 
731 -  {% if LibLLVM::IS_35 || LibLLVM::IS_36 %}
732 -    fun temporary_md_node = LLVMTemporaryMDNode(context : LibLLVM::ContextRef, mds : Metadata*, count : UInt) : Metadata
733 -    fun metadata_replace_all_uses_with = LLVMMetadataReplaceAllUsesWith(Metadata, Metadata)
734 -  {% else %}
735 -    fun di_builder_create_replaceable_composite_type = LLVMDIBuilderCreateReplaceableCompositeType(builder : DIBuilder,
736 -                                                                                                   scope : Metadata,
737 -                                                                                                   name : Char*,
738 -                                                                                                                    file : Metadata,
739 -                                                                                                   line : UInt) : Metadata
740 -    fun di_builder_replace_temporary = LLVMDIBuilderReplaceTemporary(builder : DIBuilder, from : Metadata, to : Metadata)
741 -  {% end %}
742 +  fun di_builder_create_replaceable_composite_type = LLVMDIBuilderCreateReplaceableCompositeType(builder : DIBuilder,
743 +                                                                                                 scope : Metadata,
744 +                                                                                                 name : Char*,
745 +                                                                                                 file : Metadata,
746 +                                                                                                 line : UInt) : Metadata
747 +  fun di_builder_replace_temporary = LLVMDIBuilderReplaceTemporary(builder : DIBuilder, from : Metadata, to : Metadata)
748 
749    fun set_current_debug_location = LLVMSetCurrentDebugLocation2(LibLLVM::BuilderRef, Int, Int, Metadata, Metadata)
750 
751 diff --git a/src/llvm/module.cr b/src/llvm/module.cr
752 index cb71e3b21..c15a56e77 100644
753 --- a/src/llvm/module.cr
754 +++ b/src/llvm/module.cr
755 @@ -6,7 +6,7 @@ class LLVM::Module
756 
757    getter context : Context
758 
759 -  {% if LibLLVM::IS_38 || LibLLVM::IS_36 || LibLLVM::IS_35 %}
760 +  {% if LibLLVM::IS_38 %}
761      def initialize(@unwrap : LibLLVM::ModuleRef, @name : String, @context : Context)
762        @owned = false
763      end
764 @@ -14,7 +14,7 @@ class LLVM::Module
765      def name : String
766        @name
767      end
768 -  {% else %}
769 +  {% else %} # LLVM >= 3.9
770      def initialize(@unwrap : LibLLVM::ModuleRef, @context : Context)
771        @owned = false
772      end
773 @@ -34,9 +34,9 @@ class LLVM::Module
774    end
775 
776    def data_layout=(data : TargetData)
777 -    {% if LibLLVM::IS_38 || LibLLVM::IS_36 || LibLLVM::IS_35 %}
778 +    {% if LibLLVM::IS_38 %}
779        LibLLVM.set_data_layout(self, data.to_data_layout_string)
780 -    {% else %}
781 +    {% else %} # LLVM >= 3.9
782        LibLLVM.set_module_data_layout(self, data)
783      {% end %}
784    end
785 @@ -57,11 +57,9 @@ class LLVM::Module
786      LibLLVM.write_bitcode_to_file self, filename
787    end
788 
789 -  {% unless LibLLVM::IS_35 %}
790 -    def write_bitcode_to_memory_buffer
791 -      MemoryBuffer.new(LibLLVM.write_bitcode_to_memory_buffer self)
792 -    end
793 -  {% end %}
794 +  def write_bitcode_to_memory_buffer
795 +    MemoryBuffer.new(LibLLVM.write_bitcode_to_memory_buffer self)
796 +  end
797 
798    def write_bitcode_to_fd(fd : Int, should_close = false, buffered = false)
799      LibLLVM.write_bitcode_to_fd(self, fd, should_close ? 1 : 0, buffered ? 1 : 0)
800 diff --git a/src/llvm/module_pass_manager.cr b/src/llvm/module_pass_manager.cr
801 index 10bfa60bd..519227809 100644
802 --- a/src/llvm/module_pass_manager.cr
803 +++ b/src/llvm/module_pass_manager.cr
804 @@ -3,12 +3,6 @@ class LLVM::ModulePassManager
805      @unwrap = LibLLVM.pass_manager_create
806    end
807 
808 -  {% if LibLLVM::IS_35 || LibLLVM::IS_36 %}
809 -    def add_target_data(target_data)
810 -      LibLLVM.add_target_data target_data, self
811 -    end
812 -  {% end %}
813 -
814    def run(mod)
815      LibLLVM.run_pass_manager(self, mod) != 0
816    end
817 diff --git a/src/llvm/target_machine.cr b/src/llvm/target_machine.cr
818 index e4bb081e9..42e44abe2 100644
819 --- a/src/llvm/target_machine.cr
820 +++ b/src/llvm/target_machine.cr
821 @@ -9,9 +9,9 @@ class LLVM::TargetMachine
822 
823    def data_layout
824      @layout ||= begin
825 -      layout = {% if LibLLVM::IS_38 || LibLLVM::IS_36 || LibLLVM::IS_35 %}
826 +      layout = {% if LibLLVM::IS_38 %}
827                   LibLLVM.get_target_machine_data(self)
828 -               {% else %}
829 +               {% else %} # LLVM >= 3.9
830                   LibLLVM.create_target_data_layout(self)
831                 {% end %}
832        layout ? TargetData.new(layout) : raise "Missing layout for #{self}"
833 --
834 2.14.1
835