├── .clang-format ├── .clang-tidy ├── .github └── workflows │ └── build.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE.txt ├── README.md ├── docs ├── CODE_OF_CONDUCT.md ├── book │ ├── builtin-types.md │ ├── control-flow.md │ ├── enum-types.md │ ├── functions.md │ ├── generics.md │ ├── hello-world.md │ ├── interfaces.md │ ├── introduction.md │ ├── iterators.md │ ├── list.md │ ├── low-level-programming.md │ ├── nullable-types.md │ ├── pointers.md │ ├── std.md │ ├── strings.md │ ├── structs.md │ └── variables-and-constants.md ├── build-website.sh ├── compiler-internals.md ├── cx.css ├── cx.js ├── doxyfile ├── editor.js ├── index.css ├── index.html ├── lib │ ├── codemirror.css │ ├── codemirror.js │ └── play-button.svg ├── spec │ ├── Makefile │ ├── README.md │ ├── decl.tex │ ├── expr.tex │ ├── lex.tex │ ├── spec.tex │ ├── stdlib.tex │ ├── stmt.tex │ └── type.tex ├── template.html ├── toc.html └── top-nav.html ├── examples ├── asteroids │ ├── Makefile │ ├── README.md │ ├── asteroid.cx │ ├── build.bat │ ├── game-state.cx │ ├── main.cx │ ├── missile.cx │ ├── player.cx │ └── vector2.cx ├── brainfuck.cx ├── build_examples.py ├── inputs │ ├── bench.b │ └── mandel.b ├── mandelbrot.cx ├── opengl │ ├── Makefile │ ├── fragment_shader.frag │ ├── opengl.cx │ └── vertex_shader.vert └── tree.cx ├── scripts └── format.sh ├── src ├── ast │ ├── ast-print.cpp │ ├── ast-print.h │ ├── ast.h │ ├── decl.cpp │ ├── decl.h │ ├── expr.cpp │ ├── expr.h │ ├── location.h │ ├── mangle.cpp │ ├── mangle.h │ ├── module.cpp │ ├── module.h │ ├── stmt.cpp │ ├── stmt.h │ ├── token.cpp │ ├── token.h │ ├── type.cpp │ └── type.h ├── backend │ ├── ir.cpp │ ├── ir.h │ ├── irgen-decl.cpp │ ├── irgen-expr.cpp │ ├── irgen-stmt.cpp │ ├── irgen.cpp │ ├── irgen.h │ ├── llvm.cpp │ └── llvm.h ├── driver │ ├── clang.cpp │ ├── clang.h │ ├── driver.cpp │ └── driver.h ├── package-manager │ ├── manifest.cpp │ ├── manifest.h │ ├── package-manager.cpp │ └── package-manager.h ├── parser │ ├── lex.cpp │ ├── lex.h │ ├── parse.cpp │ └── parse.h ├── pch.h ├── sema │ ├── c-import.cpp │ ├── c-import.h │ ├── null-analyzer.cpp │ ├── null-analyzer.h │ ├── typecheck-decl.cpp │ ├── typecheck-expr.cpp │ ├── typecheck-stmt.cpp │ ├── typecheck.cpp │ └── typecheck.h └── support │ ├── utility.cpp │ └── utility.h ├── std ├── ArrayIterator.cx ├── ArrayRef.cx ├── Box.cx ├── ByteIterator.cx ├── ClosedRange.cx ├── ClosedRangeIterator.cx ├── Comparable.cx ├── Copyable.cx ├── EnumeratedIterator.cx ├── FileStream.cx ├── Hashable.cx ├── Iterator.cx ├── LineIterator.cx ├── List.cx ├── Map.cx ├── MapIterator.cx ├── Optional.cx ├── OrderedMap.cx ├── OrderedMapIterator.cx ├── OrderedSet.cx ├── OrderedSetIterator.cx ├── Printable.cx ├── Queue.cx ├── Range.cx ├── RangeIterator.cx ├── Set.cx ├── SetIterator.cx ├── StringBuffer.cx ├── StringIterator.cx ├── algorithm.cx ├── allocate.cx ├── bool.cx ├── char.cx ├── error.cx ├── floats.cx ├── integers.cx ├── libc.cx ├── math.cx ├── never.cx ├── os │ ├── gnu.cx │ └── windows.cx ├── stdio.cx └── string.cx └── test ├── cat ├── check-snapshots ├── check_exit_status ├── driver ├── c-header-import-not-found.cx ├── c-header-with-error.h ├── error-in-c-header-parsing.cx └── run-unwrap-fail.cx ├── lit.cfg ├── misc ├── array-subscript-via-pointer.cx ├── comparison-operators.cx ├── composite-type-parameter-member-access.cx ├── composite-type-use-before-declaration.cx ├── composite-types.cx ├── dereference-operator.cx ├── exit-status.cx ├── explicitly-typed-mutable-variable.cx ├── extern-c-function.cx ├── generic-function-int-to-float-conversion.cx ├── generic-type-method-multiple-instantiations.cx ├── import-c-header.cx ├── import-stdarg.h.cx ├── interface.cx ├── labeled-constructor-call.cx ├── leading-underscore.cx ├── malloc-realloc-free.cx ├── member-function-call.cx ├── member-function-return-type.cx ├── module-import │ ├── main.cx │ └── mod │ │ ├── a.cx │ │ └── b.cx ├── mutable-member-mutation.cx ├── named-parameters.cx ├── nonambiguous-overloaded-constructor.cx ├── print-string-literal.cx ├── reference-operator.cx ├── return-array.cx ├── string.cx ├── tab.cx ├── uninitialized.cx ├── union-member-access.cx ├── union-member-access.h ├── variable-assignment.cx └── void-main.cx ├── not ├── parser ├── block-comment-nested-unterminated.cx ├── block-comment-nested.cx ├── block-comment-unterminated.cx ├── block-comment.cx ├── comments.cx ├── conditional-compilation.cx ├── dangling-else.cx ├── dangling-else.cx.ir ├── dangling-else.cx.ll ├── dereference-vs-multiplication.cx ├── dereference-vs-multiplication.cx.ir ├── dereference-vs-multiplication.cx.ll ├── destructor-params.cx ├── diagnostic-disjunctive-list.cx ├── else-no-brace.cx ├── else-no-brace.cx.ir ├── else-no-brace.cx.ll ├── empty-parenthesized-expression.cx ├── floating-point-literal.cx ├── floating-point-literal.cx.ir ├── floating-point-literal.cx.ll ├── global-unexpected-token.cx ├── has-include.cx ├── if-no-brace.cx ├── if-no-brace.cx.ir ├── if-no-brace.cx.ll ├── import-identifier.cx ├── inputs │ └── multifile │ │ ├── a.cx │ │ └── b.cx ├── integer-literal-only-separator.cx ├── integer-literal-prefix.cx ├── integer-literal-prefix.cx.ir ├── integer-literal-prefix.cx.ll ├── integer-literal-separator.cx ├── interface.cx ├── invalid-digit-in-nondecimal-literal.cx ├── invalid-escape-character.cx ├── leading-decimal-mark.cx ├── leading-zero.cx ├── member-operator.cx ├── mixed-case-hex-literal.cx ├── multifile.cx ├── multifile.cx.ir ├── multifile.cx.ll ├── multiple-decimal-marks.cx ├── newline-inside-string-literal.cx ├── numeric-literal-member-func-call.cx ├── numeric-literal-member-func-call.cx.ir ├── numeric-literal-member-func-call.cx.ll ├── string-literal-ends-in-backslash.cx ├── string-literal-ends-in-escaped-backslash.cx ├── too-short-nondecimal-literal.cx ├── trailing-decimal-mark.cx ├── unexpected-character-after-zero.cx ├── unknown-token.cx ├── var-decl-no-id.cx ├── var-stmt-no-semicolon.cx ├── variable-of-array-type.cx ├── variable-of-array-type.cx.ir ├── variable-of-array-type.cx.ll └── variadic-non-extern-function.cx ├── sema ├── allow-use-of-reassigned-moved-var.cx ├── ambiguous-call-with-overloaded-params.cx ├── ambiguous-constructor-call-with-overloaded-params.cx ├── assign-undefined-in-method.cx ├── assign-undefined-to-non-member-in-constructor.cx ├── assignment-of-invalid-type.cx ├── assignment-result.cx ├── assignment-to-pointer-doesnt-move.cx ├── auto-convert-literals-in-ternary-fail-else.cx ├── break-after-inner-loop.cx ├── c-enum-strongly-typed.cx ├── c-enum.cx ├── c-indirect-duplicate-import.cx ├── call-method-on-array.cx ├── call-nonfunction-variable.cx ├── cast-ptr-to-immutable-into-ptr-to-mutable.cx ├── compare-non-null-pointer-to-null.cx ├── compare-noncomparable-type.cx ├── compare-void-type.cx ├── compile-time-out-of-bounds-array-index.cx ├── composite-type-redefinition.cx ├── const-array-pointer-implicit-wrap-to-non-const.cx ├── const-increment.cx ├── const-is-transitive.cx ├── constructor-autogenerated.cx ├── copyable-struct-mutate-field.cx ├── dereference-increment-expr-stmt.cx ├── dereference-increment-expr.cx ├── dereference-nullable-pointer.cx ├── disallow-use-of-moved-param.cx ├── disallow-use-of-moved-var.cx ├── empty-array-literal.cx ├── enum-associated-value-mismatch.cx ├── enum-associated-value-order.cx ├── excess-argument-label.cx ├── explicitly-typed-variable.cx ├── expr-stmt-unused-result.cx ├── floating-point-bitwise-operation.cx ├── for-loop-ignore-loop-variable.cx ├── for-loop-over-non-iterable.cx ├── function-call-before-declaration.cx ├── function-call.cx ├── function-redefinition.cx ├── generic-arg-infer-conflict-range.cx ├── generic-arg-infer-conflict.cx ├── generic-arg-infer-fail.cx ├── generic-args-to-builtin-type.cx ├── generic-constraint-non-interface-type.cx ├── generic-constraint-unknown-type.cx ├── generic-function-failed-instantiation.cx ├── generic-function-variable-redefinition.cx ├── generic-parameter-shadows-type.cx ├── generic-type-constructor-non-existing-member.cx ├── generic-type-destructor.cx ├── illegal-cast.cx ├── illegal-subscript-index-type.cx ├── import-c-const-typedef-type.cx ├── import-header-twice │ ├── a.cx │ ├── b.cx │ └── header.h ├── imported-c-header-has-file-scope.cx ├── imported-module-has-file-scope.cx ├── increment-through-pointer-error.cx ├── index-assignment-mismatched-type.cx ├── index-assignment-overload-not-found.cx ├── infer-generic-args-in-unexpected-order.cx ├── initialize-non-null-pointer-with-null.cx ├── initialize-non-null-pointer-with-nullable-pointer.cx ├── inputs │ ├── c-enum.h │ ├── function-decl.h │ ├── import-c-const-typedef-type.h │ ├── imported-c-header-has-file-scope │ │ ├── a.h │ │ └── second-file.cx │ ├── imported-module-has-file-scope │ │ ├── foo │ │ │ └── a.cx │ │ └── second-file.cx │ ├── indirect-include.h │ └── multifile-error │ │ ├── a.cx │ │ └── b.cx ├── int-literal-argument-overflow.cx ├── int-literal-autocast.cx ├── int-literal-initializer-overflow.cx ├── interface-impl-decl-error-builtin-type.cx ├── interface-impl-decl-error-generic-param.cx ├── interface-impl-decl-error-missing-method.cx ├── interface-impl-decl-error-not-interface.cx ├── interface-impl-decl-success-generic-param.cx ├── interface-wrong-type-as-this-type.cx ├── invalid-argument-type.cx ├── invalid-arguments-to-function-pointer.cx ├── invalid-break.cx ├── invalid-operand-to-logical-not.cx ├── invalid-operands-to-logical-and.cx ├── invalid-operands-to-logical-or.cx ├── lambda-capture-field.cx ├── lambda-capture-local-variable.cx ├── lambda-capture-parameter.cx ├── lambda-infer-parameter-type-fail.cx ├── lambda-return-type-mismatch.cx ├── member-access-through-nullable-pointer.cx ├── member-function-call-through-nullable-pointer.cx ├── member-function.cx ├── mismatching-argument-label-constructor.cx ├── mismatching-argument-label.cx ├── mismatching-binary-operands.cx ├── mismatching-switch-case-value-type.cx ├── missing-generic-args.cx ├── missing-member-assignment-in-constructor.cx ├── missing-return-false-positive-1.cx ├── missing-return-false-positive-2.cx ├── missing-return.cx ├── mixed-types-in-array-literal.cx ├── move-local.cx ├── moved-in-if-branch.cx ├── moved-variable-in-generic-function.cx ├── multifile-error.cx ├── negated-int-literal-argument-overflow.cx ├── negative-uint64-literal.cx ├── no-matching-constructor-generic.cx ├── no-matching-constructor.cx ├── non-bool-if-condition.cx ├── nonexisting-member-access.cx ├── nonnullable-pointer-as-condition.cx ├── null-check-analysis │ ├── null-check-extra-unwrap-early-exit.cx │ ├── null-check-extra-unwrap-in-if-condition.cx │ ├── null-check-extra-unwrap-in-member-access.cx │ ├── null-check-extra-unwrap-in-nested-control-stmt.cx │ ├── null-check-fail-early-exit-reassigned-in-pred-block.cx │ ├── null-check-fail-early-exit-reassigned-in-same-block.cx │ ├── null-check-fail-member-access-base-expr.cx │ ├── null-check-fail-member-access.cx │ ├── null-check-fail-method.cx │ ├── null-check-fail-reassigned.cx │ ├── null-check-implicit-else-branch.cx │ ├── null-check-implicit-then-branch.cx │ ├── null-check-success-early-exit-local-variable.cx │ ├── null-check-success-early-exit.cx │ ├── null-check-success-else-branch.cx │ ├── null-check-success-from-another-variable.cx │ ├── null-check-success-logical-or.cx │ ├── null-check-success-member-access.cx │ ├── null-check-success-method.cx │ ├── null-check-success-previously-unwrapped.cx │ ├── null-check-success-reassigned-unwrapped-value.cx │ └── null-check-success-then-branch.cx ├── null-unsized-array-reference-cast.cx ├── parameter-shadows-global-function.cx ├── parameter-shadows-member-function-ambiguous.cx ├── pointer-equals-incompatible-pointee-types.cx ├── pointer-invalid-binary-op.cx ├── pointer-to-pointer-auto-dereference.cx ├── pointer-to-rvalue-assign.cx ├── pointer-to-rvalue-return.cx ├── pointer-to-rvalue.cx ├── prefer-exact-param-type-match-if-ambiguous.cx ├── prefer-stdlib-if-ambiguous.cx ├── private-enum │ ├── a.cx │ └── private-enum.cx ├── private-global-function │ ├── a.cx │ └── private-global-function.cx ├── private-global-variable │ ├── a.cx │ └── private-global-variable.cx ├── private-interface-member.cx ├── private-member-function │ ├── a.cx │ └── private-member-function.cx ├── private-member-variable │ ├── a.cx │ └── private-member-variable.cx ├── private-type │ ├── a.cx │ └── private-type.cx ├── report-multiple-errors.cx ├── resolve-generic-parameter-preserve-mutability.cx ├── return-array-with-wrong-size.cx ├── return-no-value-in-non-void-function.cx ├── return-pointer-to-local-variable.cx ├── return-result-of-generic-func.cx ├── return-value-in-void-function.cx ├── sizeof-variable.cx ├── stdlib-ambigous-reference-false-positive │ ├── a.cx │ └── a.h ├── switch-mutable-condition.cx ├── template-not-unused.cx ├── too-few-arguments.cx ├── too-few-generic-arguments.cx ├── too-many-arguments.cx ├── too-many-generic-arguments-on-type.cx ├── too-many-generic-arguments.cx ├── tuple-equality.cx ├── tuple-mismatching-element-name-inferred.cx ├── tuple-mismatching-element-name.cx ├── type-not-specified-to-implement-interface.cx ├── unknown-function.cx ├── unknown-identifier-in-generic-type-member-func.cx ├── unknown-member-access-base.cx ├── unknown-variable.cx ├── unnecessary-builtin-conversion.cx ├── unsatisfied-generic-constraint.cx ├── unsupported-member-access.cx ├── unsupported-subscript.cx ├── untyped-null.cx ├── use-imported-name-in-generic-func │ ├── inputs │ │ ├── header.h │ │ └── module.cx │ └── main.cx ├── variable-redefinition.cx ├── variable-without-initializer.cx ├── variadic-function-too-few-args.cx └── void-return.cx ├── snapshot ├── allocas-in-multiple-constructors.cx ├── allocas-in-multiple-constructors.cx.ir ├── allocas-in-multiple-constructors.cx.ll ├── and-or.cx ├── and-or.cx.ir ├── and-or.cx.ll ├── argument-auto-reference.cx ├── argument-auto-reference.cx.ir ├── argument-auto-reference.cx.ll ├── array-literal-non-constant-elements.cx ├── array-literal-non-constant-elements.cx.ir ├── array-literal-non-constant-elements.cx.ll ├── array-literal.cx ├── array-literal.cx.ir ├── array-literal.cx.ll ├── array-of-string-literals.cx ├── array-of-string-literals.cx.ir ├── array-of-string-literals.cx.ll ├── array-pointer-auto-wrap.cx ├── array-pointer-auto-wrap.cx.ir ├── array-pointer-auto-wrap.cx.ll ├── array-ref-auto-reference.cx ├── array-ref-auto-reference.cx.ir ├── array-ref-auto-reference.cx.ll ├── array-ref-pointer.cx ├── array-ref-pointer.cx.ir ├── array-ref-pointer.cx.ll ├── asm-label-attribute.cx ├── asm-label-attribute.cx.ir ├── asm-label-attribute.cx.ll ├── asm-label-attribute.h ├── assert.cx ├── assert.cx.ir ├── assert.cx.ll ├── assign-undefined-in-constructor.cx ├── assign-undefined-in-constructor.cx.ir ├── assign-undefined-in-constructor.cx.ll ├── assignment.cx ├── assignment.cx.ir ├── assignment.cx.ll ├── auto-convert-array-literal-elements.cx ├── auto-convert-array-literal-elements.cx.ir ├── auto-convert-array-literal-elements.cx.ll ├── auto-convert-literals-in-ternary.cx ├── auto-convert-literals-in-ternary.cx.ir ├── auto-convert-literals-in-ternary.cx.ll ├── auto-deref-arithmetic.cx ├── auto-deref-arithmetic.cx.ir ├── auto-deref-arithmetic.cx.ll ├── auto-deref-subscript-result.cx ├── auto-deref-subscript-result.cx.ir ├── auto-deref-subscript-result.cx.ll ├── auto-generated-move-constructor.cx ├── auto-generated-move-constructor.cx.ir ├── auto-generated-move-constructor.cx.ll ├── bitwise-operators.cx ├── bitwise-operators.cx.ir ├── bitwise-operators.cx.ll ├── boolean-literal.cx ├── boolean-literal.cx.ir ├── boolean-literal.cx.ll ├── box.cx ├── box.cx.ir ├── box.cx.ll ├── break.cx ├── break.cx.ir ├── break.cx.ll ├── bug-with-destructor-call-codegen.cx ├── bug-with-destructor-call-codegen.cx.ir ├── bug-with-destructor-call-codegen.cx.ll ├── builtin-type-auto-reference.cx ├── builtin-type-auto-reference.cx.ir ├── builtin-type-auto-reference.cx.ll ├── c-callback-function │ ├── c-callback-function.cx │ ├── c-callback-function.cx.ir │ ├── c-callback-function.cx.ll │ └── c-callback-function.h ├── c-strings.cx ├── c-strings.cx.ir ├── c-strings.cx.ll ├── compare-nullable-and-nonnull-ptrs.cx ├── compare-nullable-and-nonnull-ptrs.cx.ir ├── compare-nullable-and-nonnull-ptrs.cx.ll ├── compare-pointer-to-integer.cx ├── compare-pointer-to-integer.cx.ir ├── compare-pointer-to-integer.cx.ll ├── compound-assignment-rhs-precedence.cx ├── compound-assignment-rhs-precedence.cx.ir ├── compound-assignment-rhs-precedence.cx.ll ├── compound-assignment.cx ├── compound-assignment.cx.ir ├── compound-assignment.cx.ll ├── constant-macro.cx ├── constant-macro.cx.ir ├── constant-macro.cx.ll ├── constant-macro.h ├── constructor-autogenerated.cx ├── constructor-autogenerated.cx.ir ├── constructor-autogenerated.cx.ll ├── constructor-call-before-declaration.cx ├── constructor-call-before-declaration.cx.ir ├── constructor-call-before-declaration.cx.ll ├── constructor-delegation.cx ├── constructor-delegation.cx.ir ├── constructor-delegation.cx.ll ├── continue.cx ├── continue.cx.ir ├── continue.cx.ll ├── conversion-to-bool.cx ├── conversion-to-bool.cx.ir ├── conversion-to-bool.cx.ll ├── copyable-empty-destructor.cx ├── copyable-empty-destructor.cx.ir ├── copyable-empty-destructor.cx.ll ├── copyable-type-auto-reference.cx ├── copyable-type-auto-reference.cx.ir ├── copyable-type-auto-reference.cx.ll ├── copyable-type-definition.cx ├── copyable-type-definition.cx.ir ├── copyable-type-definition.cx.ll ├── copyable-type-member-function.cx ├── copyable-type-member-function.cx.ir ├── copyable-type-member-function.cx.ll ├── copyable-type-member-pointer-access-without-dereference.cx ├── copyable-type-member-pointer-access-without-dereference.cx.ir ├── copyable-type-member-pointer-access-without-dereference.cx.ll ├── copyable-type-method-call-before-declaration.cx ├── copyable-type-method-call-before-declaration.cx.ir ├── copyable-type-method-call-before-declaration.cx.ll ├── copyable-type-mutate-this.cx ├── copyable-type-mutate-this.cx.ir ├── copyable-type-mutate-this.cx.ll ├── copyable-type-mutating-function-member-access.cx ├── copyable-type-mutating-function-member-access.cx.ir ├── copyable-type-mutating-function-member-access.cx.ll ├── deep-nested-generics.cx ├── deep-nested-generics.cx.ir ├── deep-nested-generics.cx.ll ├── defer.cx ├── defer.cx.ir ├── defer.cx.ll ├── destructor-calls-member-destructors.cx ├── destructor-calls-member-destructors.cx.ir ├── destructor-calls-member-destructors.cx.ll ├── destructor.cx ├── destructor.cx.ir ├── destructor.cx.ll ├── discarding-assignment.cx ├── discarding-assignment.cx.ir ├── discarding-assignment.cx.ll ├── empty-composite-type.cx ├── empty-composite-type.cx.ir ├── empty-composite-type.cx.ll ├── empty-string-literal.cx ├── empty-string-literal.cx.ir ├── empty-string-literal.cx.ll ├── enum-associated-values.cx ├── enum-associated-values.cx.ir ├── enum-associated-values.cx.ll ├── enum-typed-field.cx ├── enum-typed-field.cx.ir ├── enum-typed-field.cx.ll ├── enum.cx ├── enum.cx.ir ├── enum.cx.ll ├── escape-character.cx ├── escape-character.cx.ir ├── escape-character.cx.ll ├── exclusive-range-operator.cx ├── exclusive-range-operator.cx.ir ├── exclusive-range-operator.cx.ll ├── explicit-destructor-call.cx ├── explicit-destructor-call.cx.ir ├── explicit-destructor-call.cx.ll ├── field-default-value.cx ├── field-default-value.cx.ir ├── field-default-value.cx.ll ├── float-arithmetic.cx ├── float-arithmetic.cx.ir ├── float-arithmetic.cx.ll ├── float-constant-auto-cast.cx ├── float-constant-auto-cast.cx.ir ├── float-constant-auto-cast.cx.ll ├── float-literal-auto-cast.cx ├── float-literal-auto-cast.cx.ir ├── float-literal-auto-cast.cx.ll ├── foo.h ├── for-loop-c-style.cx ├── for-loop-c-style.cx.ir ├── for-loop-c-style.cx.ll ├── for-loop-continue.cx ├── for-loop-continue.cx.ir ├── for-loop-continue.cx.ll ├── for-loop.cx ├── for-loop.cx.ir ├── for-loop.cx.ll ├── function-pointer-local-variable.cx ├── function-pointer-local-variable.cx.ir ├── function-pointer-local-variable.cx.ll ├── function-pointer-member-variable.cx ├── function-pointer-member-variable.cx.ir ├── function-pointer-member-variable.cx.ll ├── function-pointer-parameter.cx ├── function-pointer-parameter.cx.ir ├── function-pointer-parameter.cx.ll ├── function.cx ├── function.cx.ir ├── function.cx.ll ├── generic-arg-infer-conflict-skipped.cx ├── generic-arg-infer-conflict-skipped.cx.ir ├── generic-arg-infer-conflict-skipped.cx.ll ├── generic-arg-infer-in-constructor-call.cx ├── generic-arg-infer-in-constructor-call.cx.ir ├── generic-arg-infer-in-constructor-call.cx.ll ├── generic-argument-inference-deep.cx ├── generic-argument-inference-deep.cx.ir ├── generic-argument-inference-deep.cx.ll ├── generic-function.cx ├── generic-function.cx.ir ├── generic-function.cx.ll ├── generic-method-on-generic-type.cx ├── generic-method-on-generic-type.cx.ir ├── generic-method-on-generic-type.cx.ll ├── generic-method-use-return-type.cx ├── generic-method-use-return-type.cx.ir ├── generic-method-use-return-type.cx.ll ├── generic-method.cx ├── generic-method.cx.ir ├── generic-method.cx.ll ├── generic-param-0-arg-constructor-call.cx ├── generic-param-0-arg-constructor-call.cx.ir ├── generic-param-0-arg-constructor-call.cx.ll ├── generic-param-as-null-type.cx ├── generic-param-as-null-type.cx.ir ├── generic-param-as-null-type.cx.ll ├── generic-param-use-inside-method.cx ├── generic-param-use-inside-method.cx.ir ├── generic-param-use-inside-method.cx.ll ├── generic-type-constructor-call-in-another-module.cx ├── generic-type-constructor-call-in-another-module.cx.ir ├── generic-type-constructor-call-in-another-module.cx.ll ├── generic-type-destructor.cx ├── generic-type-destructor.cx.ir ├── generic-type-destructor.cx.ll ├── generic-type-generic-param-in-constructor-params.cx ├── generic-type-generic-param-in-constructor-params.cx.ir ├── generic-type-generic-param-in-constructor-params.cx.ll ├── generic-type-member-func-using-generic-param-2.cx ├── generic-type-member-func-using-generic-param-2.cx.ir ├── generic-type-member-func-using-generic-param-2.cx.ll ├── generic-type-member-func-using-generic-param.cx ├── generic-type-member-func-using-generic-param.cx.ir ├── generic-type-member-func-using-generic-param.cx.ll ├── generic-type-member-func.cx ├── generic-type-member-func.cx.ir ├── generic-type-member-func.cx.ll ├── generic-type-member-using-generic-param.cx ├── generic-type-member-using-generic-param.cx.ir ├── generic-type-member-using-generic-param.cx.ll ├── generic-type-method-call.cx ├── generic-type-method-call.cx.ir ├── generic-type-method-call.cx.ll ├── generic-type-method-calls-without-this.cx ├── generic-type-method-calls-without-this.cx.ir ├── generic-type-method-calls-without-this.cx.ll ├── generic-type.cx ├── generic-type.cx.ir ├── generic-type.cx.ll ├── global-constant.cx ├── global-constant.cx.ir ├── global-constant.cx.ll ├── global-ptr-to-copyable-as-argument.cx ├── global-ptr-to-copyable-as-argument.cx.ir ├── global-ptr-to-copyable-as-argument.cx.ll ├── global-variable.cx ├── global-variable.cx.ir ├── global-variable.cx.ll ├── if-expression.cx ├── if-expression.cx.ir ├── if-expression.cx.ll ├── if-statement.cx ├── if-statement.cx.ir ├── if-statement.cx.ll ├── implicit-cast-to-void-pointer.cx ├── implicit-cast-to-void-pointer.cx.ir ├── implicit-cast-to-void-pointer.cx.ll ├── implicit-null-comparison-pointer.cx ├── implicit-null-comparison-pointer.cx.ir ├── implicit-null-comparison-pointer.cx.ll ├── import-c-define-integer-hex-constant.cx ├── import-c-define-integer-hex-constant.cx.ir ├── import-c-define-integer-hex-constant.cx.ll ├── import-c-enum.cx ├── import-c-enum.cx.ir ├── import-c-enum.cx.ll ├── import-c-header.cx ├── import-c-header.cx.ir ├── import-c-header.cx.ll ├── import-c-pointer-to-pointer-null-conversion.cx ├── import-c-pointer-to-pointer-null-conversion.cx.ir ├── import-c-pointer-to-pointer-null-conversion.cx.ll ├── import-c-typedefed-anonymous-struct.cx ├── import-c-typedefed-anonymous-struct.cx.ir ├── import-c-typedefed-anonymous-struct.cx.ll ├── increment-through-pointer.cx ├── increment-through-pointer.cx.ir ├── increment-through-pointer.cx.ll ├── infer-generic-args-autoreference.cx ├── infer-generic-args-autoreference.cx.ir ├── infer-generic-args-autoreference.cx.ll ├── infer-generic-args-forget-mutable.cx ├── infer-generic-args-forget-mutable.cx.ir ├── infer-generic-args-forget-mutable.cx.ll ├── infer-generic-args-reinterpret-int-literal.cx ├── infer-generic-args-reinterpret-int-literal.cx.ir ├── infer-generic-args-reinterpret-int-literal.cx.ll ├── infer-generic-arguments-from-assignment-lhs.cx ├── infer-generic-arguments-from-assignment-lhs.cx.ir ├── infer-generic-arguments-from-assignment-lhs.cx.ll ├── inheritance.cx ├── inheritance.cx.ir ├── inheritance.cx.ll ├── inputs │ ├── copyable-type-method-call-before-declaration │ │ ├── a.cx │ │ └── b.cx │ ├── import-c-defined-integer-hex-constant.h │ ├── import-c-enum.h │ ├── import-c-pointer-to-pointer-null-conversion.h │ ├── import-c-typedefed-anonymous-struct.h │ └── imported_generic_type_constructor │ │ └── a.cx ├── int-literal-autocast.cx ├── int-literal-autocast.cx.ir ├── int-literal-autocast.cx.ll ├── int-literal-plus-float-literal.cx ├── int-literal-plus-float-literal.cx.ir ├── int-literal-plus-float-literal.cx.ll ├── integer-literal.cx ├── integer-literal.cx.ir ├── integer-literal.cx.ll ├── interface-method-definition.cx ├── interface-method-definition.cx.ir ├── interface-method-definition.cx.ll ├── interface-this-type.cx ├── interface-this-type.cx.ir ├── interface-this-type.cx.ll ├── interface.cx ├── interface.cx.ir ├── interface.cx.ll ├── iterate-static-array.cx ├── iterate-static-array.cx.ir ├── iterate-static-array.cx.ll ├── lambda-noncapturing.cx ├── lambda-noncapturing.cx.ir ├── lambda-noncapturing.cx.ll ├── local-auto-reference.cx ├── local-auto-reference.cx.ir ├── local-auto-reference.cx.ll ├── loop-variable-name-reuse.cx ├── loop-variable-name-reuse.cx.ir ├── loop-variable-name-reuse.cx.ll ├── member-access-via-pointer.cx ├── member-access-via-pointer.cx.ir ├── member-access-via-pointer.cx.ll ├── member-array-subscript.cx ├── member-array-subscript.cx.ir ├── member-array-subscript.cx.ll ├── member-func-call-without-this.cx ├── member-func-call-without-this.cx.ir ├── member-func-call-without-this.cx.ll ├── member-function-call-in-lambda-body.cx ├── member-function-call-in-lambda-body.cx.ir ├── member-function-call-in-lambda-body.cx.ll ├── member-function-call-via-local-pointer.cx ├── member-function-call-via-local-pointer.cx.ir ├── member-function-call-via-local-pointer.cx.ll ├── member-function-call-via-pointer-parameter.cx ├── member-function-call-via-pointer-parameter.cx.ir ├── member-function-call-via-pointer-parameter.cx.ll ├── member-function-on-different-types.cx ├── member-function-on-different-types.cx.ir ├── member-function-on-different-types.cx.ll ├── member-function.cx ├── member-function.cx.ir ├── member-function.cx.ll ├── method-call-on-returned-value.cx ├── method-call-on-returned-value.cx.ir ├── method-call-on-returned-value.cx.ll ├── method-return-void.cx ├── method-return-void.cx.ir ├── method-return-void.cx.ll ├── move-return-value.cx ├── move-return-value.cx.ir ├── move-return-value.cx.ll ├── move-type-with-destructor.cx ├── move-type-with-destructor.cx.ir ├── move-type-with-destructor.cx.ll ├── mutable-local-var-in-generic-function.cx ├── mutable-local-var-in-generic-function.cx.ir ├── mutable-local-var-in-generic-function.cx.ll ├── negate-generic-parameter.cx ├── negate-generic-parameter.cx.ir ├── negate-generic-parameter.cx.ll ├── nested-generic-calls-2.cx ├── nested-generic-calls-2.cx.ir ├── nested-generic-calls-2.cx.ll ├── nested-generic-calls.cx ├── nested-generic-calls.cx.ir ├── nested-generic-calls.cx.ll ├── never.cx ├── never.cx.ir ├── never.cx.ll ├── not.cx ├── not.cx.ir ├── not.cx.ll ├── null-pointer.cx ├── null-pointer.cx.ir ├── null-pointer.cx.ll ├── null-unsized-array-reference.cx ├── null-unsized-array-reference.cx.ir ├── null-unsized-array-reference.cx.ll ├── numeric-conversion.cx ├── numeric-conversion.cx.ir ├── numeric-conversion.cx.ll ├── operator-overloading.cx ├── operator-overloading.cx.ir ├── operator-overloading.cx.ll ├── optional-pointer-access-without-unwrapping.cx ├── optional-pointer-access-without-unwrapping.cx.ir ├── optional-pointer-access-without-unwrapping.cx.ll ├── optional-type-comparison.cx ├── optional-type-comparison.cx.ir ├── optional-type-comparison.cx.ll ├── optional-type-non-pointer-return.cx ├── optional-type-non-pointer-return.cx.ir ├── optional-type-non-pointer-return.cx.ll ├── optional-type-non-pointer.cx ├── optional-type-non-pointer.cx.ir ├── optional-type-non-pointer.cx.ll ├── optional-type-unknown-identifier-bug.cx ├── optional-type-unknown-identifier-bug.cx.ir ├── optional-type-unknown-identifier-bug.cx.ll ├── overloaded-generic-operator-function.cx ├── overloaded-generic-operator-function.cx.ir ├── overloaded-generic-operator-function.cx.ll ├── overloading-with-param-names.cx ├── overloading-with-param-names.cx.ir ├── overloading-with-param-names.cx.ll ├── overloading-with-param-types.cx ├── overloading-with-param-types.cx.ir ├── overloading-with-param-types.cx.ll ├── own-member-access-without-this.cx ├── own-member-access-without-this.cx.ir ├── own-member-access-without-this.cx.ll ├── packed-struct.cx ├── packed-struct.cx.ir ├── packed-struct.cx.ll ├── packed-struct.h ├── parameter-auto-reference.cx ├── parameter-auto-reference.cx.ir ├── parameter-auto-reference.cx.ll ├── parameter-shadows-member-function.cx ├── parameter-shadows-member-function.cx.ir ├── parameter-shadows-member-function.cx.ll ├── parameter-shadows-member-variable.cx ├── parameter-shadows-member-variable.cx.ir ├── parameter-shadows-member-variable.cx.ll ├── pass-constant-by-pointer.cx ├── pass-constant-by-pointer.cx.ir ├── pass-constant-by-pointer.cx.ll ├── pass-non-null-pointer-as-nullable.cx ├── pass-non-null-pointer-as-nullable.cx.ir ├── pass-non-null-pointer-as-nullable.cx.ll ├── pass-temporary-object-by-pointer.cx ├── pass-temporary-object-by-pointer.cx.ir ├── pass-temporary-object-by-pointer.cx.ll ├── pointer-comparison-operator.cx ├── pointer-comparison-operator.cx.ir ├── pointer-comparison-operator.cx.ll ├── pointer-comparison.cx ├── pointer-comparison.cx.ir ├── pointer-comparison.cx.ll ├── pointer-constructor.cx ├── pointer-constructor.cx.ir ├── pointer-constructor.cx.ll ├── pointer-to-array-of-pointers.cx ├── pointer-to-array-of-pointers.cx.ir ├── pointer-to-array-of-pointers.cx.ll ├── pointer-to-array-with-unknown-size.cx ├── pointer-to-array-with-unknown-size.cx.ir ├── pointer-to-array-with-unknown-size.cx.ll ├── range-type.cx ├── range-type.cx.ir ├── range-type.cx.ll ├── reassign-type-with-destructor.cx ├── reassign-type-with-destructor.cx.ir ├── reassign-type-with-destructor.cx.ll ├── recursive-generic-enum.cx ├── recursive-generic-enum.cx.ir ├── recursive-generic-enum.cx.ll ├── recursive-type.cx ├── recursive-type.cx.ir ├── recursive-type.cx.ll ├── return-inside-if.cx ├── return-inside-if.cx.ir ├── return-inside-if.cx.ll ├── return-statement.cx ├── return-statement.cx.ir ├── return-statement.cx.ll ├── return-value-auto-reference.cx ├── return-value-auto-reference.cx.ir ├── return-value-auto-reference.cx.ll ├── reuse-variable-name-in-unrelated-scope.cx ├── reuse-variable-name-in-unrelated-scope.cx.ir ├── reuse-variable-name-in-unrelated-scope.cx.ll ├── signed-vs-unsigned-arithmetic.cx ├── signed-vs-unsigned-arithmetic.cx.ir ├── signed-vs-unsigned-arithmetic.cx.ll ├── stack-allocated-array-of-pointers.cx ├── stack-allocated-array-of-pointers.cx.ir ├── stack-allocated-array-of-pointers.cx.ll ├── string-literal.cx ├── string-literal.cx.ir ├── string-literal.cx.ll ├── string-plus-assign.cx ├── string-plus-assign.cx.ir ├── string-plus-assign.cx.ll ├── struct-with-destructor-as-value-param.cx ├── struct-with-destructor-as-value-param.cx.ir ├── struct-with-destructor-as-value-param.cx.ll ├── switch.cx ├── switch.cx.ir ├── switch.cx.ll ├── temporary-unsized-array-argument.cx ├── temporary-unsized-array-argument.cx.ir ├── temporary-unsized-array-argument.cx.ll ├── tuple-return-by-pointer.cx ├── tuple-return-by-pointer.cx.ir ├── tuple-return-by-pointer.cx.ll ├── tuple.cx ├── tuple.cx.ir ├── tuple.cx.ll ├── uninitialized-global.cx ├── uninitialized-global.cx.ir ├── uninitialized-global.cx.ll ├── unsized-array.cx ├── unsized-array.cx.ir ├── unsized-array.cx.ll ├── unwrap.cx ├── unwrap.cx.ir ├── unwrap.cx.ll ├── var-decl-in-control-flow-condition.cx ├── var-decl-in-control-flow-condition.cx.ir ├── var-decl-in-control-flow-condition.cx.ll ├── variable-shadowing.cx ├── variable-shadowing.cx.ir ├── variable-shadowing.cx.ll ├── variadic-c-function.cx ├── variadic-c-function.cx.ir ├── variadic-c-function.cx.ll ├── variadic-function-decl.cx ├── variadic-function-decl.cx.ir ├── variadic-function-decl.cx.ll ├── void-main-return.cx ├── void-main-return.cx.ir ├── void-main-return.cx.ll ├── while-loop.cx ├── while-loop.cx.ir └── while-loop.cx.ll ├── stdlib ├── algorithm-tests.cx ├── arrayref-tests.cx ├── char-tests.cx ├── compare-tests.cx ├── empty-list-removeFirst.cx ├── empty-list-removeLast.cx ├── file-tests.cx ├── list-destroy-elements-in-destructor.cx ├── list-filter-map.cx ├── list-out-of-bounds-access.cx ├── list-tests.cx ├── map-tests.cx ├── ordered-map-tests.cx ├── ordered-set-tests.cx ├── print-tests.cx ├── printable-tests.cx ├── queue-tests.cx ├── range-tests.cx ├── set-tests.cx ├── string-substr-out-of-bounds.cx └── string-tests.cx └── true /.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: 2 | -*, 3 | readability-braces-around-statements 4 | WarningsAsErrors: 5 | readability-braces-around-statements 6 | FormatStyle: file 7 | CheckOptions: 8 | - key: readability-braces-around-statements.ShortStatementLines 9 | value: 1 10 | -------------------------------------------------------------------------------- /docs/book/generics.md: -------------------------------------------------------------------------------- 1 | # Generics 2 | 3 | TODO 4 | 5 | ## Generic constraints 6 | 7 | TODO 8 | -------------------------------------------------------------------------------- /docs/book/iterators.md: -------------------------------------------------------------------------------- 1 | # Iterators 2 | 3 | Iterators are objects used to traverse through the elements of a collections. 4 | 5 | ## How to create a custom iterator 6 | 7 | TODO 8 | -------------------------------------------------------------------------------- /docs/book/std.md: -------------------------------------------------------------------------------- 1 | # Standard library reference 2 | 3 | Documentation for the C* standard library is not yet available. 4 | 5 | Meanwhile, you can look at the standard library sources to see what's available: 6 | {target="_blank"} 7 | -------------------------------------------------------------------------------- /docs/compiler-internals.md: -------------------------------------------------------------------------------- 1 | # Compiler Internals 2 | 3 | ## Nullability analysis 4 | 5 | During type-checking, optional types are implicitly unwrapped when needed. 6 | After type-checking, nullability analysis phase emits warnings for null-safety violations. 7 | -------------------------------------------------------------------------------- /docs/doxyfile: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = cx 2 | INPUT = . docs src 3 | RECURSIVE = YES 4 | USE_MDFILE_AS_MAINPAGE = README.md 5 | EXTRACT_ALL = YES 6 | EXCLUDE_SYMBOLS = llvm clang 7 | OUTPUT_DIRECTORY = docs 8 | GENERATE_LATEX = NO 9 | HAVE_DOT = YES 10 | DOT_IMAGE_FORMAT = svg 11 | CALLER_GRAPH = YES 12 | BUILTIN_STL_SUPPORT = YES 13 | -------------------------------------------------------------------------------- /docs/spec/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | pdflatex spec.tex 3 | -------------------------------------------------------------------------------- /docs/spec/README.md: -------------------------------------------------------------------------------- 1 | To render spec.pdf from the LaTeX sources, run `make`. 2 | -------------------------------------------------------------------------------- /examples/asteroids/Makefile: -------------------------------------------------------------------------------- 1 | SHELL := bash 2 | 3 | all: 4 | cx build $$(pkg-config sdl2 --cflags --libs) -lm 5 | -------------------------------------------------------------------------------- /examples/asteroids/build.bat: -------------------------------------------------------------------------------- 1 | cx -c *.cx -I%SDLDIR%\include -fms-extensions 2 | lld-link output.obj -LIBPATH:%SDLDIR%\lib\x64 SDL2.lib legacy_stdio_definitions.lib ucrt.lib msvcrt.lib -DEBUG 3 | -------------------------------------------------------------------------------- /examples/inputs/bench.b: -------------------------------------------------------------------------------- 1 | Benchmark brainf*ck program 2 | >++[<+++++++++++++>-]<[[>+>+<<-]>[<+>-]++++++++ 3 | [>++++++++<-]>.[-]<<>++++++++++[>++++++++++[>++ 4 | ++++++++[>++++++++++[>++++++++++[>++++++++++[>+ 5 | +++++++++[-]<-]<-]<-]<-]<-]<-]<-]++++++++++. 6 | -------------------------------------------------------------------------------- /examples/opengl/fragment_shader.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 color; 4 | 5 | void main() 6 | { 7 | color = vec4(1, 0, 0, 1); 8 | } 9 | -------------------------------------------------------------------------------- /examples/opengl/vertex_shader.vert: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout(location = 0) in vec3 vertexPosition_modelspace; 4 | 5 | void main() 6 | { 7 | gl_Position.xyz = vertexPosition_modelspace; 8 | gl_Position.w = 1.0; 9 | } 10 | -------------------------------------------------------------------------------- /src/ast/mangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace cx { 6 | 7 | struct FunctionDecl; 8 | 9 | std::string mangleFunctionDecl(const FunctionDecl& functionDecl); 10 | 11 | } // namespace cx 12 | -------------------------------------------------------------------------------- /src/driver/clang.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace llvm { 4 | template 5 | class ArrayRef; 6 | } 7 | 8 | namespace cx { 9 | 10 | int invokeClang(llvm::ArrayRef args); 11 | 12 | } // namespace cx 13 | -------------------------------------------------------------------------------- /src/driver/driver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace cx { 7 | 8 | struct CompileOptions { 9 | bool noUnusedWarnings; 10 | std::vector importSearchPaths; 11 | std::vector frameworkSearchPaths; 12 | std::vector defines; 13 | std::vector cflags; 14 | }; 15 | 16 | } // namespace cx 17 | -------------------------------------------------------------------------------- /src/package-manager/package-manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace llvm { 7 | class StringRef; 8 | } 9 | 10 | namespace cx { 11 | 12 | void fetchDependencies(llvm::StringRef packageRoot); 13 | std::vector getSourceFiles(llvm::StringRef rootDirectory, llvm::StringRef packageManifestPath); 14 | 15 | } // namespace cx 16 | -------------------------------------------------------------------------------- /std/Box.cx: -------------------------------------------------------------------------------- 1 | struct Box { 2 | T* pointer; 3 | 4 | Box(T value) { 5 | this.pointer = allocate(value); 6 | } 7 | 8 | // Box(T* pointer) { 9 | // this.pointer = pointer; 10 | // } 11 | 12 | ~Box() { 13 | deallocate(pointer); 14 | } 15 | 16 | T* get() { 17 | return pointer; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /std/Copyable.cx: -------------------------------------------------------------------------------- 1 | interface Copyable {} 2 | -------------------------------------------------------------------------------- /std/Hashable.cx: -------------------------------------------------------------------------------- 1 | interface Hashable { 2 | // TODO: Should probably return int since Map just casts it to int anyway. 3 | uint64 hash(); 4 | } 5 | -------------------------------------------------------------------------------- /std/Printable.cx: -------------------------------------------------------------------------------- 1 | interface Printable { 2 | // TODO: Make this member function take any OutputStream as an argument once the compiler supports it. 3 | void print(StringBuffer* stream); 4 | 5 | StringBuffer toString() { 6 | var result = StringBuffer(); 7 | this.print(result); 8 | return result; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /std/bool.cx: -------------------------------------------------------------------------------- 1 | struct bool: Copyable, Comparable, Printable, Hashable { 2 | Ordering compare(bool* other) { 3 | return int(this).compare(int(other)); 4 | } 5 | 6 | void print(StringBuffer* stream) { 7 | stream.write(this ? "true" : "false"); 8 | } 9 | 10 | uint64 hash() { 11 | return uint64(this); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /std/math.cx: -------------------------------------------------------------------------------- 1 | T abs(T value) { 2 | if (value < 0) { 3 | return -value; 4 | } else { 5 | return value; 6 | } 7 | } 8 | 9 | T clamp(T value, T min, T max) { 10 | if (value < min) return min; 11 | if (value > max) return max; 12 | return value; 13 | } 14 | -------------------------------------------------------------------------------- /std/never.cx: -------------------------------------------------------------------------------- 1 | /// Placeholder type used as the return type for functions that do not return. 2 | struct never {} 3 | -------------------------------------------------------------------------------- /test/cat: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | 5 | with open(sys.argv[1], 'r') as file: 6 | print(file.read()) 7 | -------------------------------------------------------------------------------- /test/check_exit_status: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import subprocess 5 | 6 | given_exit_status = int(sys.argv[1]) 7 | actual_exit_status = subprocess.call(sys.argv[2:]) 8 | 9 | if actual_exit_status != given_exit_status: 10 | print("FAIL: expected exit status: {}, actual exit status: {}".format(hex(given_exit_status), hex(actual_exit_status))) 11 | sys.exit(1) 12 | -------------------------------------------------------------------------------- /test/driver/c-header-import-not-found.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+2]]:8: error: couldn't find C header file 'foo.h' 4 | // CHECK: [[@LINE+1]]:8: error: couldn't import C header file 'foo.h' 5 | import "foo.h"; // TODO: Make this emit only one error. 6 | 7 | void main() {} 8 | -------------------------------------------------------------------------------- /test/driver/c-header-with-error.h: -------------------------------------------------------------------------------- 1 | typedef foo bar; 2 | -------------------------------------------------------------------------------- /test/driver/error-in-c-header-parsing.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s 2>&1 | %FileCheck %s 2 | 3 | // CHECK: c-header-with-error.h:1:9: error: unknown type name 'foo' 4 | // CHECK: [[@LINE+1]]:8: error: couldn't import C header file 'c-header-with-error.h' 5 | import "c-header-with-error.h"; 6 | 7 | void main() {} 8 | -------------------------------------------------------------------------------- /test/driver/run-unwrap-fail.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx run %s 2>&1 | %FileCheck -match-full-lines %s 2 | 3 | void main() { 4 | int*? p = null; 5 | // CHECK: Unwrap failed at run-unwrap-fail.cx:[[@LINE+1]]:15 6 | var pp = p!; 7 | } 8 | -------------------------------------------------------------------------------- /test/misc/array-subscript-via-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx run %s | %FileCheck -match-full-lines -strict-whitespace %s 2 | // CHECK:Foo 3 | 4 | import "stdlib.h"; 5 | import "stdio.h"; 6 | 7 | void main() { 8 | var buffer = cast(malloc(4)!); 9 | buffer[0] = 70; 10 | buffer[1] = 0x6f; 11 | buffer[2] = 0o157; 12 | buffer[3] = 0b0; 13 | puts(cast(cast(buffer))); 14 | } 15 | -------------------------------------------------------------------------------- /test/misc/composite-type-parameter-member-access.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 15 %cx run %s 2 | 3 | struct vec2: Copyable { 4 | int x; 5 | int y; 6 | 7 | vec2 add(vec2 that) { 8 | return vec2(this.x + that.x, this.y + that.y); 9 | } 10 | } 11 | 12 | int main() { 13 | var foo = vec2(5, 8); 14 | var foo2 = foo.add(vec2(3, -1)); 15 | return foo2.x + foo2.y; 16 | } 17 | -------------------------------------------------------------------------------- /test/misc/composite-type-use-before-declaration.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 2 %cx run %s 2 | 3 | int main() { return 2; } 4 | void foo(Foo a) { } 5 | struct Foo { int i; } 6 | -------------------------------------------------------------------------------- /test/misc/composite-types.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 5 %cx run %s 2 | 3 | struct Foo: Copyable { } 4 | struct Bar { } 5 | 6 | struct X: Copyable { 7 | int a; 8 | } 9 | 10 | struct Y { 11 | char* y; 12 | } 13 | 14 | int main() { 15 | var x = X(5); 16 | return x.a; 17 | } 18 | -------------------------------------------------------------------------------- /test/misc/dereference-operator.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 42 %cx run %s 2 | 3 | extern void* calloc(uint64 count, uint64 size); 4 | 5 | int main() { 6 | var buffer = cast(calloc(1, 8)); 7 | *buffer = 41; 8 | (*buffer)++; 9 | return *buffer; 10 | } 11 | -------------------------------------------------------------------------------- /test/misc/exit-status.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 42 %cx run %s 2 | 3 | int main() { return getExitStatus(); } 4 | int getExitStatus() { return 42; } 5 | -------------------------------------------------------------------------------- /test/misc/explicitly-typed-mutable-variable.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 3 %cx run %s 2 | 3 | int main() { 4 | int m = 4; 5 | m--; 6 | return m; 7 | } 8 | -------------------------------------------------------------------------------- /test/misc/extern-c-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx run %s | %FileCheck -match-full-lines -strict-whitespace %s 2 | // CHECK:foo 3 | 4 | int main() { 5 | putchar(102); 6 | putchar(111); 7 | putchar(111); 8 | putchar(10); 9 | return 0; 10 | } 11 | 12 | extern int putchar(int ch); 13 | -------------------------------------------------------------------------------- /test/misc/generic-function-int-to-float-conversion.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -print-llvm %s 2 | 3 | bool foo(T t) { 4 | return t < 0; 5 | } 6 | 7 | void main() { 8 | _ = foo(5.0); 9 | } 10 | -------------------------------------------------------------------------------- /test/misc/generic-type-method-multiple-instantiations.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -print-llvm %s 2 | 3 | struct S: Copyable { 4 | void f(T t) { 5 | var v = t 6 | } 7 | } 8 | 9 | void main() { 10 | S().f(1) 11 | S().f(false) 12 | } 13 | -------------------------------------------------------------------------------- /test/misc/import-c-header.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx run %s | %FileCheck -match-full-lines -strict-whitespace %s 2 | // CHECK:foo bar 3 | 4 | import "stdio.h"; 5 | 6 | void main() { 7 | printf("foo bar"); 8 | } 9 | -------------------------------------------------------------------------------- /test/misc/import-stdarg.h.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 0 %cx run %s 2 | 3 | import "stdarg.h"; 4 | 5 | void main() { } 6 | -------------------------------------------------------------------------------- /test/misc/interface.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -print-llvm %s 2 | 3 | interface Fooable { 4 | void foo(); 5 | } 6 | 7 | struct F: Copyable, Fooable { 8 | void foo() { } 9 | } 10 | 11 | void main() { 12 | F f = undefined; 13 | bar(f); 14 | } 15 | 16 | void bar(T t) { 17 | t.foo(); 18 | } 19 | -------------------------------------------------------------------------------- /test/misc/labeled-constructor-call.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -print-llvm %s 2 | void main() { 3 | var a = Foo(qux: 4); 4 | } 5 | struct Foo: Copyable { 6 | Foo(int qux) { } 7 | } 8 | -------------------------------------------------------------------------------- /test/misc/leading-underscore.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 42 %cx run %s 2 | 3 | int _foo() { return 42; } 4 | int main() { return _foo(); } 5 | -------------------------------------------------------------------------------- /test/misc/malloc-realloc-free.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 0 %cx run %s 2 | 3 | import "stdlib.h"; 4 | 5 | void main() { 6 | var buffer = malloc(1); 7 | buffer = realloc(buffer, 4); 8 | free(buffer); 9 | } 10 | -------------------------------------------------------------------------------- /test/misc/member-function-call.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 42 %cx run %s 2 | 3 | struct Foo { 4 | int i; 5 | 6 | Foo() { 7 | this.i = 0; 8 | } 9 | 10 | void add(int amount) { 11 | this.i = this.i + amount; 12 | } 13 | } 14 | 15 | int main() { 16 | var f = Foo(); 17 | f.add(21); 18 | f.add(21); 19 | return f.i; 20 | } 21 | -------------------------------------------------------------------------------- /test/misc/member-function-return-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 21 %cx run %s 2 | 3 | struct Foo: Copyable { 4 | int value; 5 | 6 | int add(int number) { 7 | return this.value + number; 8 | } 9 | } 10 | 11 | int main() { 12 | var foo = Foo(42); 13 | return foo.add(-21); 14 | } 15 | -------------------------------------------------------------------------------- /test/misc/module-import/main.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx run %s | %FileCheck -match-full-lines -strict-whitespace %s 2 | 3 | // CHECK:foo!!! 4 | // CHECK-NEXT:bar!!! 5 | 6 | import mod; 7 | 8 | void main() { 9 | foo(); 10 | bar(); 11 | } 12 | -------------------------------------------------------------------------------- /test/misc/module-import/mod/a.cx: -------------------------------------------------------------------------------- 1 | // RUN: true 2 | 3 | import "stdio.h" 4 | 5 | void foo() { 6 | puts("foo!!!") 7 | } 8 | -------------------------------------------------------------------------------- /test/misc/module-import/mod/b.cx: -------------------------------------------------------------------------------- 1 | // RUN: true 2 | 3 | import "stdio.h" 4 | 5 | void bar() { 6 | puts("bar!!!") 7 | } 8 | -------------------------------------------------------------------------------- /test/misc/mutable-member-mutation.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 6 %cx run %s 2 | 3 | struct X: Copyable { 4 | int a; 5 | } 6 | 7 | int main() { 8 | var x = X(0); 9 | x.a = 5; 10 | x.a++; 11 | return x.a; 12 | } 13 | -------------------------------------------------------------------------------- /test/misc/named-parameters.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 5 %cx run %s 2 | 3 | int f(int a, bool b) { return a; } 4 | int main() { 5 | return f(a: 5, b: false); 6 | } 7 | -------------------------------------------------------------------------------- /test/misc/nonambiguous-overloaded-constructor.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -print-llvm %s 2 | 3 | struct Foo: Copyable { 4 | Foo(int a) { } 5 | Foo(int a, int b) { } 6 | } 7 | 8 | void main() { 9 | var f = Foo(1) 10 | } 11 | -------------------------------------------------------------------------------- /test/misc/reference-operator.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx run %s | %FileCheck -match-full-lines -strict-whitespace %s 2 | // CHECK:Bar 3 | 4 | extern int puts(uint8* s); 5 | 6 | void main() { 7 | uint8[4] buffer = undefined; 8 | var ptr = &buffer; 9 | ptr[0] = 66; 10 | ptr[1] = 0x61; 11 | ptr[2] = 0o162; 12 | ptr[3] = 0b0; 13 | puts(&buffer[0]); 14 | } 15 | -------------------------------------------------------------------------------- /test/misc/string.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 11 %cx run %s 2 | 3 | int main() { 4 | return "abc".size() + foo("quux"); 5 | } 6 | 7 | int foo(string x) { 8 | var s = x; 9 | s = bar(x); 10 | return x.size() + bar(s).size(); 11 | } 12 | 13 | string bar(string z) { 14 | return z; 15 | } 16 | -------------------------------------------------------------------------------- /test/misc/tab.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:10: error: unknown identifier 'b' 5 | var a = b; 6 | } 7 | -------------------------------------------------------------------------------- /test/misc/uninitialized.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 70 %cx run %s 2 | 3 | int main() { 4 | uint8[4] buffer = undefined; 5 | buffer[0] = 70; 6 | buffer[1] = 0x6f; 7 | buffer[2] = 0o157; 8 | buffer[3] = 0b0; 9 | 10 | uint8 magic = undefined; 11 | if (buffer[0] == 0) { 12 | magic = 0; 13 | } else { 14 | magic = buffer[0]; 15 | } 16 | return int(magic); 17 | } 18 | -------------------------------------------------------------------------------- /test/misc/union-member-access.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 42 %cx run %s 2 | 3 | import "union-member-access.h" 4 | 5 | int foo(U u) { 6 | return u.b 7 | } 8 | 9 | int main() { 10 | U u = undefined 11 | u.a = 21 12 | return foo(u) + u.b 13 | } 14 | -------------------------------------------------------------------------------- /test/misc/union-member-access.h: -------------------------------------------------------------------------------- 1 | union U { 2 | int a; 3 | int b; 4 | }; 5 | -------------------------------------------------------------------------------- /test/misc/variable-assignment.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 42 %cx run %s 2 | 3 | int main() { 4 | var i = -1; 5 | i = 42; 6 | return i; 7 | } 8 | -------------------------------------------------------------------------------- /test/misc/void-main.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 0 %cx run %s 2 | 3 | void main() { } 4 | -------------------------------------------------------------------------------- /test/not: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import subprocess 5 | 6 | exit_status = subprocess.call(sys.argv[1:]) 7 | 8 | if exit_status == 0: 9 | sys.exit(1) 10 | else: 11 | sys.exit(0) 12 | -------------------------------------------------------------------------------- /test/parser/block-comment-nested-unterminated.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:1: error: unterminated block comment 4 | /* 5 | /* 6 | */ 7 | -------------------------------------------------------------------------------- /test/parser/block-comment-nested.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -parse %s 2 | 3 | /* 4 | /* 5 | foo 6 | */ 7 | */ 8 | -------------------------------------------------------------------------------- /test/parser/block-comment-unterminated.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s 2 | 3 | // CHECK: [[@LINE+1]]:1: error: unterminated block comment 4 | /* 5 | -------------------------------------------------------------------------------- /test/parser/block-comment.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -parse %s 2 | 3 | /* 4 | foo 5 | */ 6 | -------------------------------------------------------------------------------- /test/parser/comments.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -parse %s 2 | 3 | // line comment 4 | -------------------------------------------------------------------------------- /test/parser/dangling-else.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | int main() { 4 | // TODO: Emit warning for dangling else. 5 | if (true) 6 | if (false) 7 | return 1; 8 | else 9 | return 0; 10 | 11 | return 2; 12 | } 13 | -------------------------------------------------------------------------------- /test/parser/dangling-else.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | br bool true, if.then, if.else 4 | 5 | if.then: 6 | br bool false, if.then, if.else 7 | 8 | if.else: 9 | br if.end 10 | 11 | if.end: 12 | return int 2 13 | 14 | if.then_0: 15 | return int 1 16 | 17 | if.else_0: 18 | return int 0 19 | 20 | if.end_0: 21 | br if.end 22 | } 23 | -------------------------------------------------------------------------------- /test/parser/dereference-vs-multiplication.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | int g() { 4 | return 1 5 | } 6 | 7 | void f(int* a, int b) { 8 | var m = g() 9 | *a = b 10 | var n = g() 11 | *b 12 | } 13 | -------------------------------------------------------------------------------- /test/parser/dereference-vs-multiplication.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int _EN4main1gE() { 3 | return int 1 4 | } 5 | 6 | void _EN4main1fEP3int3int(int* a, int b) { 7 | int* m = alloca int 8 | int* n = alloca int 9 | int _0 = call _EN4main1gE() 10 | store _0 to m 11 | store b to a 12 | int _1 = call _EN4main1gE() 13 | int _2 = _1 * b 14 | store _2 to n 15 | return void 16 | } 17 | -------------------------------------------------------------------------------- /test/parser/destructor-params.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | struct Foo: Copyable { 4 | // CHECK: [[@LINE+1]]:5: error: destructors cannot have parameters 5 | ~Foo(int i) { } 6 | } 7 | -------------------------------------------------------------------------------- /test/parser/diagnostic-disjunctive-list.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck -strict-whitespace %s 2 | 3 | void main() { 4 | // TODO: Should say 'expected type'. 5 | // CHECK: [[@LINE+1]]:15: error: unexpected '>' 6 | var a = A<>(); 7 | } 8 | -------------------------------------------------------------------------------- /test/parser/else-no-brace.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | int main() { 4 | if (true) { 5 | return 1; 6 | } else 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /test/parser/else-no-brace.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | br bool true, if.then, if.else 4 | 5 | if.then: 6 | return int 1 7 | 8 | if.else: 9 | return int 0 10 | 11 | if.end: 12 | unreachable 13 | } 14 | -------------------------------------------------------------------------------- /test/parser/else-no-brace.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | br i1 true, label %if.then, label %if.else 4 | 5 | if.then: ; preds = %0 6 | ret i32 1 7 | 8 | if.else: ; preds = %0 9 | ret i32 0 10 | } 11 | -------------------------------------------------------------------------------- /test/parser/empty-parenthesized-expression.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:9: error: unexpected ')' 5 | if () { 6 | 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/parser/floating-point-literal.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | var a = 0.009; 4 | -------------------------------------------------------------------------------- /test/parser/floating-point-literal.cx.ir: -------------------------------------------------------------------------------- 1 | global a = float 0.00899999961 2 | -------------------------------------------------------------------------------- /test/parser/floating-point-literal.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | @a = private global float 0x3F826E9780000000 3 | -------------------------------------------------------------------------------- /test/parser/global-unexpected-token.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:2: error: unexpected 'this' 4 | this 5 | -------------------------------------------------------------------------------- /test/parser/has-include.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -print-llvm %s | %FileCheck %s -allow-empty 2 | 3 | #if !hasInclude("stdio.h") 4 | // CHECK-NOT: stdio 5 | var a = "stdio"; 6 | #endif 7 | 8 | #if hasInclude("should-not-exist.h") 9 | // CHECK-NOT: should-not-exist 10 | var a = "should-not-exist"; 11 | #endif 12 | -------------------------------------------------------------------------------- /test/parser/if-no-brace.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | int main() { 4 | if false return 1; 5 | 6 | if true 7 | return 2; 8 | 9 | return 3; 10 | } 11 | -------------------------------------------------------------------------------- /test/parser/if-no-brace.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | br bool false, if.then, if.else 4 | 5 | if.then: 6 | return int 1 7 | 8 | if.else: 9 | br if.end 10 | 11 | if.end: 12 | br bool true, if.then, if.else 13 | 14 | if.then_0: 15 | return int 2 16 | 17 | if.else_0: 18 | br if.end_0 19 | 20 | if.end_0: 21 | return int 3 22 | } 23 | -------------------------------------------------------------------------------- /test/parser/import-identifier.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:8: error: expected identifier or string literal after 'import', got '<' 4 | import 5 | -------------------------------------------------------------------------------- /test/parser/inputs/multifile/a.cx: -------------------------------------------------------------------------------- 1 | var a = 42; 2 | -------------------------------------------------------------------------------- /test/parser/inputs/multifile/b.cx: -------------------------------------------------------------------------------- 1 | var b = 42; 2 | -------------------------------------------------------------------------------- /test/parser/integer-literal-only-separator.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:9: error: hex literal must have at least one digit after '0x' 4 | var i = 0x__; 5 | -------------------------------------------------------------------------------- /test/parser/integer-literal-prefix.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | int foo() { 4 | return (0 - -0xC) * (0o4 + 0b11 * 2); 5 | } 6 | -------------------------------------------------------------------------------- /test/parser/integer-literal-prefix.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int _EN4main3fooE() { 3 | return int 120 4 | } 5 | -------------------------------------------------------------------------------- /test/parser/integer-literal-prefix.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @_EN4main3fooE() { 3 | ret i32 120 4 | } 5 | -------------------------------------------------------------------------------- /test/parser/integer-literal-separator.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -parse %s 2 | 3 | var a = 1_000__000_; 4 | var b = 0x_ff_ab30__; 5 | var c = 0b_10_11__; 6 | var d = 0o_54_23__; 7 | -------------------------------------------------------------------------------- /test/parser/interface.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -parse %s 2 | 3 | interface I { 4 | void i(); 5 | int* j(); 6 | } 7 | -------------------------------------------------------------------------------- /test/parser/invalid-digit-in-nondecimal-literal.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:16: error: invalid digit '8' in octal literal 4 | var a = 0o000378; 5 | -------------------------------------------------------------------------------- /test/parser/invalid-escape-character.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:14: error: unknown escape character '\z' 4 | var a = " \z" 5 | -------------------------------------------------------------------------------- /test/parser/leading-decimal-mark.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:12: error: unexpected '.' 4 | var half = .5; 5 | -------------------------------------------------------------------------------- /test/parser/leading-zero.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:13: error: numbers cannot start with 0[0-9], use 0o prefix for octal literal 5 | var i = 0666; 6 | } 7 | -------------------------------------------------------------------------------- /test/parser/member-operator.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | struct Foo: Copyable { 4 | // CHECK: 5:10: error: operator functions other than 'operator[]' must be non-member functions 5 | bool operator==(Foo f) { return false } 6 | } 7 | -------------------------------------------------------------------------------- /test/parser/mixed-case-hex-literal.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:16: error: mixed letter case in hex literal 5 | var i = 0xfF; 6 | } 7 | -------------------------------------------------------------------------------- /test/parser/multifile.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots %p/inputs/multifile/a.cx %p/inputs/multifile/b.cx 2 | -------------------------------------------------------------------------------- /test/parser/multifile.cx.ir: -------------------------------------------------------------------------------- 1 | global a = int 42 2 | global b = int 42 3 | -------------------------------------------------------------------------------- /test/parser/multifile.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | @a = private global i32 42 3 | @b = private global i32 42 4 | -------------------------------------------------------------------------------- /test/parser/multiple-decimal-marks.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:14: error: expected identifier, got number 4 | var pi = 3.1.4; 5 | -------------------------------------------------------------------------------- /test/parser/newline-inside-string-literal.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:15: error: newline inside string literal 5 | var i = "a 6 | "; 7 | } 8 | -------------------------------------------------------------------------------- /test/parser/numeric-literal-member-func-call.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var foo = 0.hash(); 5 | } 6 | -------------------------------------------------------------------------------- /test/parser/numeric-literal-member-func-call.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | uint64* foo = alloca uint64 4 | int* _0 = alloca int 5 | store int 0 to _0 6 | uint64 _1 = call _EN3std3int4hashE(int* _0) 7 | store _1 to foo 8 | return int 0 9 | } 10 | 11 | uint64 _EN3std3int4hashE(int* this) { 12 | int this.load = load this 13 | uint64 _0 = cast this.load to uint64 14 | return _0 15 | } 16 | -------------------------------------------------------------------------------- /test/parser/string-literal-ends-in-backslash.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+2]]:15: error: newline inside string literal 4 | // CHECK: {{^ \^$}} 5 | var a = " \" 6 | -------------------------------------------------------------------------------- /test/parser/string-literal-ends-in-escaped-backslash.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -parse %s 2 | 3 | var a = " \\" 4 | -------------------------------------------------------------------------------- /test/parser/too-short-nondecimal-literal.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:9: error: hex literal must have at least one digit after '0x' 4 | var a = 0x; 5 | -------------------------------------------------------------------------------- /test/parser/trailing-decimal-mark.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:12: error: expected identifier, got ';' 4 | var pi = 3.; 5 | -------------------------------------------------------------------------------- /test/parser/unexpected-character-after-zero.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:14: error: expected newline or ';', got identifier 5 | var i = 0a; 6 | } 7 | -------------------------------------------------------------------------------- /test/parser/unknown-token.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:1: error: unknown token '`' 4 | ` 5 | // CHECK: [[@LINE+1]]:1: error: expected identifier, got end-of-file 6 | -------------------------------------------------------------------------------- /test/parser/var-decl-no-id.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:5: error: expected identifier, got number 4 | var 1 5 | -------------------------------------------------------------------------------- /test/parser/var-stmt-no-semicolon.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -parse %s 2 | 3 | void main() { 4 | var a = 5 5 | } 6 | -------------------------------------------------------------------------------- /test/parser/variable-of-array-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | int[3] foo = [0, 1, 2]; 4 | 5 | void main() { 6 | int[1] qux = [42]; 7 | foo[0] = 3; 8 | foo[1].hash(); 9 | } 10 | -------------------------------------------------------------------------------- /test/parser/variadic-non-extern-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -parse %s | %FileCheck %s 2 | 3 | // TODO: Improve error message to say "expected type, got '...'" 4 | // CHECK: [[@LINE+1]]:15: error: unexpected '...' 5 | void f(int i, ...) {} 6 | -------------------------------------------------------------------------------- /test/sema/allow-use-of-reassigned-moved-var.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | struct A {} 4 | 5 | void main() { 6 | var a = A(); 7 | var b = a; 8 | a = A(); 9 | var c = a; 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/assign-undefined-in-method.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct A { 4 | int i; 5 | 6 | void f() { 7 | // CHECK: [[@LINE+1]]:13: error: 'undefined' is only allowed as an initial value 8 | i = undefined; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/assign-undefined-to-non-member-in-constructor.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct A { 4 | int i; 5 | 6 | A() { 7 | var j = 0; 8 | // CHECK: [[@LINE+1]]:13: error: 'undefined' is only allowed as an initial value 9 | j = undefined; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sema/assignment-of-invalid-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | var b = false; 5 | // CHECK: [[@LINE+1]]:7: error: cannot assign 'int' to 'bool' 6 | b = 1; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/assignment-result.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | var a = 1; 5 | // CHECK: [[@LINE+1]]:7: error: cannot assign 'void' to 'int' 6 | a = (a = 2); 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/assignment-to-pointer-doesnt-move.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | struct X {} 4 | 5 | void f(X x) { 6 | X*? p = null; 7 | p = x; 8 | p = x; 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/auto-convert-literals-in-ternary-fail-else.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | uint8 foo(bool b) { 4 | // CHECK: [[@LINE+1]]:22: error: 1000 is out of range for type 'uint8' 5 | return b ? 100 : 1000; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/break-after-inner-loop.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | void main() { 4 | while (false) { 5 | while (false) { 6 | } 7 | break; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/c-enum-strongly-typed.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | import "./inputs/c-enum.h"; 4 | 5 | void baz(Foo f) {} 6 | 7 | void main() { 8 | baz(FOO); 9 | // CHECK: [[@LINE+1]]:9: error: invalid argument #1 type 'int' to 'baz', expected 'Foo' 10 | baz(42); 11 | } 12 | -------------------------------------------------------------------------------- /test/sema/c-enum.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | import "inputs/c-enum.h"; 4 | 5 | void main() { 6 | uint u = FOO; 7 | int i = FOO; 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/c-indirect-duplicate-import.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s | %FileCheck %s -allow-empty 2 | 3 | import "inputs/function-decl.h"; 4 | import "inputs/indirect-include.h"; 5 | 6 | void main() { 7 | // CHECK-NOT: ambiguous reference 8 | test(); 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/call-method-on-array.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | var a = [1, 2, 3]; 5 | // CHECK: [[@LINE+1]]:5: error: type 'int[3]' has no member function 'foo' 6 | a.foo(); 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/call-nonfunction-variable.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | var foo = 5; 5 | // CHECK: [[@LINE+1]]:15: error: 'foo' is not a function 6 | var bar = foo(); 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/cast-ptr-to-immutable-into-ptr-to-mutable.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void f(const void* v) { 4 | // CHECK: [[@LINE+1]]:13: error: illegal cast from 'const void*' to 'int*' 5 | var p = cast(v); 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/compare-non-null-pointer-to-null.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | var i = 42; 5 | var p = &i; 6 | // CHECK: [[@LINE+1]]:11: error: invalid operands 'int*' and 'null' to '==' (non-optional type 'int*' cannot be null) 7 | if (p == null) { } 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/compare-noncomparable-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct X {} 4 | 5 | void fx(X* a, X* b) { 6 | // CHECK: [[@LINE+1]]:12: error: type 'X' doesn't implement interface 'Comparable' 7 | _ = *a < *b; 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/compare-void-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void f(void* a, void* b) { 4 | // CHECK: [[@LINE+1]]:8: error: invalid operands 'void' and 'void' to '==' 5 | *a == *b; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/compile-time-out-of-bounds-array-index.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s | %FileCheck %s 2 | 3 | extern int[5]* foo(); 4 | 5 | void main() { 6 | var p = foo(); 7 | // CHECK: [[@LINE+1]]:15: warning: accessing array out-of-bounds with index 5, array size is 5 8 | var e = p[5]; 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/const-increment.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | extern const int* f(); 4 | 5 | void main() { 6 | var i = f(); 7 | // CHECK: [[@LINE+1]]:9: error: cannot increment immutable value of type 'const int' 8 | (*i)++; 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/const-is-transitive.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct Foo: Copyable { 4 | int a 5 | } 6 | 7 | void bar(const Foo* foo) { 8 | // CHECK: [[@LINE+1]]:11: error: cannot assign to immutable variable 'a' of type 'const int' 9 | foo.a = 42 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/copyable-struct-mutate-field.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | struct A: Copyable { 4 | int s 5 | 6 | void a() { 7 | s++ 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/dereference-increment-expr-stmt.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void f(int* p) { 4 | var a = p; 5 | 6 | // CHECK: [[@LINE+1]]:5: error: cannot dereference non-pointer type 'void' 7 | *(a++); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/dereference-increment-expr.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void f(int[*] p) { 4 | var a = p; 5 | 6 | // CHECK: [[@LINE+1]]:13: error: cannot dereference non-pointer type 'void' 7 | var b = *(a++); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/dereference-nullable-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s | %FileCheck %s 2 | 3 | struct Foo: Copyable { 4 | int i; 5 | } 6 | 7 | void main() { 8 | Foo*? p = null; 9 | // CHECK: [[@LINE+1]]:9: warning: dereferenced pointer may be null; unwrap it with a postfix '!' to silence this warning 10 | _ = *p; 11 | } 12 | -------------------------------------------------------------------------------- /test/sema/disallow-use-of-moved-param.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct T {} 4 | 5 | void f(T t) {} 6 | 7 | void g(T t) { 8 | f(t); 9 | // CHECK: [[@LINE+1]]:13: error: use of moved value 10 | var a = t; 11 | } 12 | -------------------------------------------------------------------------------- /test/sema/disallow-use-of-moved-var.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct T {} 4 | 5 | void f(T t) {} 6 | 7 | void g() { 8 | var t = T(); 9 | f(t); 10 | // CHECK: [[@LINE+1]]:7: error: use of moved value 11 | f(t); 12 | } 13 | -------------------------------------------------------------------------------- /test/sema/enum-associated-value-mismatch.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | enum E { 4 | A(int a, int b) 5 | } 6 | 7 | void main() { 8 | // CHECK: [[@LINE+1]]:16: error: too few arguments to 'A', expected 2 9 | var a = E.A(a: 1); 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/enum-associated-value-order.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | enum E { 4 | A(int a, int b) 5 | } 6 | 7 | void main() { 8 | // CHECK: [[@LINE+1]]:17: error: invalid argument name 'b' for parameter 'a' 9 | var a = E.A(b: 1, a: 2); 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/excess-argument-label.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void f(int a) { } 4 | 5 | void main() { 6 | // CHECK: [[@LINE+1]]:7: error: invalid argument name 'foo' for parameter 'a' 7 | f(foo: 0); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/explicitly-typed-variable.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:13: error: cannot assign 'bool' to 'int' 5 | int i = false; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/expr-stmt-unused-result.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -print-llvm %s | %FileCheck %s -allow-empty 2 | 3 | void main() { 4 | 2 + 2; 5 | } 6 | -------------------------------------------------------------------------------- /test/sema/floating-point-bitwise-operation.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:17: error: invalid operands 'float' and 'float' to '&' 5 | var a = 5.0 & 2.0; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/for-loop-ignore-loop-variable.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck -Werror %s 2 | 3 | void main() { 4 | for (var _ in "foo") {} 5 | } 6 | -------------------------------------------------------------------------------- /test/sema/for-loop-over-non-iterable.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct A {} 4 | 5 | void main() { 6 | // CHECK: [[@LINE+1]]:5: error: unknown identifier 'A.iterator' 7 | for (var i in A()) {} 8 | // CHECK-NOT: error 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/function-call-before-declaration.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | void main() { foo(); } 4 | void foo() { } 5 | -------------------------------------------------------------------------------- /test/sema/function-call.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | int foo() { return 42; } 4 | void bar() { } 5 | 6 | void main() { 7 | var i = foo(); 8 | bar(); 9 | foo(); 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/function-redefinition.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void foo() { } 4 | // CHECK: [[@LINE+2]]:6: error: redefinition of 'foo' 5 | // CHECK: :3:6: note: previous definition here 6 | void foo() { } 7 | 8 | void bar(int a) { } 9 | // CHECK: [[@LINE+2]]:6: error: redefinition of 'bar' 10 | // CHECK: :8:6: note: previous definition here 11 | void bar(int b) { } 12 | -------------------------------------------------------------------------------- /test/sema/generic-arg-infer-conflict-range.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void f(uint a) { 4 | // CHECK: [[@LINE+1]]:22: error: no matching operator '..' with arguments 'float' and 'uint' 5 | for (var i in 0.0..a) {} 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/generic-arg-infer-conflict.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void foo(T a, T b) { } 4 | 5 | // CHECK: [[@LINE+2]]:15: error: no matching function 'foo(int, bool)' 6 | // CHECK: :3:6: note: candidate function: 7 | void main() { foo(1, false) } 8 | -------------------------------------------------------------------------------- /test/sema/generic-arg-infer-fail.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void foo() { } 4 | 5 | // CHECK: [[@LINE+1]]:18: error: can't infer generic parameters, please specify them explicitly 6 | void main() { foo() } 7 | -------------------------------------------------------------------------------- /test/sema/generic-args-to-builtin-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:1: error: too many generic arguments to 'int', expected 0 4 | int f() { 5 | return 42; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/generic-constraint-non-interface-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:11: error: only interface types can be used as generic constraints 4 | void f() {} 5 | 6 | struct Foo {} 7 | -------------------------------------------------------------------------------- /test/sema/generic-constraint-unknown-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:11: error: unknown type 'Foo' 4 | void f() {} 5 | -------------------------------------------------------------------------------- /test/sema/generic-function-failed-instantiation.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | bool foo(T t) { 4 | // CHECK: [[@LINE+1]]:14: error: invalid operands 'bool' and 'int' to '<' 5 | return t < 3; 6 | } 7 | 8 | void main() { 9 | _ = foo(false); 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/generic-function-variable-redefinition.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | void a() { 4 | var i = 1 5 | b() 6 | } 7 | 8 | void b() { 9 | var i = 1 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/generic-parameter-shadows-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct Foo: Copyable { } 4 | 5 | // CHECK: [[@LINE+2]]:10: error: redefinition of 'Foo' 6 | // CHECK: :3:8: note: previous definition here 7 | void bar() { } 8 | -------------------------------------------------------------------------------- /test/sema/generic-type-constructor-non-existing-member.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct A { 4 | // CHECK: 5:16: error: no member named 'd' in 'A' 5 | A() { this.d = 3 } 6 | } 7 | 8 | void main() { var a = A() } 9 | -------------------------------------------------------------------------------- /test/sema/generic-type-destructor.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct C { 4 | ~C() { 5 | // CHECK: [[@LINE+1]]:17: error: unknown identifier 'b' 6 | var a = b 7 | } 8 | } 9 | 10 | void main() { 11 | var c = C() 12 | } 13 | -------------------------------------------------------------------------------- /test/sema/illegal-cast.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:13: error: illegal cast from 'bool' to 'int**' 5 | var i = cast(false); 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/illegal-subscript-index-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | extern int[5]* foo(); 4 | 5 | void main() { 6 | var p = foo(); 7 | // CHECK: [[@LINE+1]]:15: error: illegal index type 'bool', expected 'int' 8 | var e = p[false]; 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/import-c-const-typedef-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | import "inputs/import-c-const-typedef-type.h"; 4 | 5 | void main() { 6 | var i = 0; 7 | bar(&i); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/import-header-twice/a.cx: -------------------------------------------------------------------------------- 1 | // RUN: true 2 | 3 | import "header.h" 4 | 5 | var a = 42 6 | -------------------------------------------------------------------------------- /test/sema/import-header-twice/b.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck ./a.cx ./b.cx | %FileCheck -allow-empty %s 2 | 3 | import "header.h" 4 | 5 | void main() { 6 | // CHECK-NOT: error: ambiguous reference to 'foo' 7 | foo(a) 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/import-header-twice/header.h: -------------------------------------------------------------------------------- 1 | #ifndef CX_HEADER_H_INCLUDED 2 | #define CX_HEADER_H_INCLUDED 3 | 4 | void foo(int f); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /test/sema/imported-c-header-has-file-scope.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s %p/inputs/imported-c-header-has-file-scope/second-file.cx | %FileCheck %s 2 | 3 | import "inputs/imported-c-header-has-file-scope/a.h" 4 | 5 | // CHECK: second-file.cx:2:5: error: unknown identifier 'foo' 6 | -------------------------------------------------------------------------------- /test/sema/imported-module-has-file-scope.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s %p/inputs/imported-module-has-file-scope/second-file.cx | %FileCheck %s 2 | 3 | import foo; 4 | 5 | // CHECK: second-file.cx:2:5: error: unknown identifier 'foo' 6 | -------------------------------------------------------------------------------- /test/sema/increment-through-pointer-error.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void f(bool* a) { 4 | var p = a; 5 | // CHECK: [[@LINE+1]]:6: error: cannot increment 'bool' 6 | p++; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/index-assignment-mismatched-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | int[3] x = [1,2,3]; 5 | // CHECK: [[@LINE+1]]:12: error: cannot assign 'bool' to 'int' 6 | x[1] = false; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/index-assignment-overload-not-found.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct S {} 4 | 5 | void main() { 6 | var s = S() 7 | 8 | // CHECK: [[@LINE+1]]:6: error: unknown identifier 'S.[]=' 9 | s[1] = 2 // TODO: Improve error message to say something like "S doesn't provide an operator[]=" 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/infer-generic-args-in-unexpected-order.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | void foo(C c, B b, A a) { } 4 | 5 | void main() { foo(5, false, "bar") } 6 | -------------------------------------------------------------------------------- /test/sema/initialize-non-null-pointer-with-null.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:14: error: cannot assign 'null' to 'int*' (add '?' to the type to make it nullable) 5 | int* p = null; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/initialize-non-null-pointer-with-nullable-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | extern int*? foo(); 4 | 5 | void main() { 6 | // CHECK: [[@LINE+1]]:17: error: cannot assign 'int*?' to 'int*' 7 | int* f = foo(); // TODO: Implicitly unwrap with warning 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/inputs/c-enum.h: -------------------------------------------------------------------------------- 1 | // RUN: %cx -print-llvm -Iinputs %s | %FileCheck %s 2 | 3 | typedef enum { 4 | FOO = 42 5 | } Foo; 6 | -------------------------------------------------------------------------------- /test/sema/inputs/function-decl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | void test(void); 4 | -------------------------------------------------------------------------------- /test/sema/inputs/import-c-const-typedef-type.h: -------------------------------------------------------------------------------- 1 | typedef void foo; 2 | extern bar(const foo* p); 3 | -------------------------------------------------------------------------------- /test/sema/inputs/imported-c-header-has-file-scope/a.h: -------------------------------------------------------------------------------- 1 | void foo(); 2 | -------------------------------------------------------------------------------- /test/sema/inputs/imported-c-header-has-file-scope/second-file.cx: -------------------------------------------------------------------------------- 1 | void main() { 2 | foo() 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/inputs/imported-module-has-file-scope/foo/a.cx: -------------------------------------------------------------------------------- 1 | void foo() { } 2 | -------------------------------------------------------------------------------- /test/sema/inputs/imported-module-has-file-scope/second-file.cx: -------------------------------------------------------------------------------- 1 | void main() { 2 | foo() 3 | } 4 | -------------------------------------------------------------------------------- /test/sema/inputs/indirect-include.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "function-decl.h" 4 | -------------------------------------------------------------------------------- /test/sema/inputs/multifile-error/a.cx: -------------------------------------------------------------------------------- 1 | var a = 42; 2 | -------------------------------------------------------------------------------- /test/sema/inputs/multifile-error/b.cx: -------------------------------------------------------------------------------- 1 | var b = foo; 2 | // CHECK:{{.*}}multifile-error/b.cx:[[@LINE-1]]:9: error: unknown identifier 'foo' 3 | // CHECK-NEXT:var b = foo; 4 | // CHECK-NEXT: ^ 5 | -------------------------------------------------------------------------------- /test/sema/int-literal-argument-overflow.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void foo(uint8 a) { } 4 | 5 | void main() { 6 | // CHECK: [[@LINE+1]]:9: error: 256 is out of range for type 'uint8' 7 | foo(256); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/int-literal-initializer-overflow.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:14: error: 128 is out of range for type 'int8' 5 | int8 b = 128; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/interface-impl-decl-error-builtin-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:14: error: 'int' is not an interface 4 | struct Z: int {} 5 | 6 | void main() { 7 | var z = Z(); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/interface-impl-decl-error-generic-param.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:14: error: 'bool' is not an interface 4 | struct Z: T {} 5 | 6 | void main() { 7 | var z = Z(); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/interface-impl-decl-error-missing-method.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | interface X { 4 | void foo(); 5 | } 6 | 7 | // CHECK: [[@LINE+1]]:8: error: 'Z' doesn't have member function 'foo' required by interface 'X' 8 | struct Z: X {} 9 | 10 | void main() { 11 | var z = Z(); 12 | } 13 | -------------------------------------------------------------------------------- /test/sema/interface-impl-decl-error-not-interface.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:14: error: 'StringBuffer' is not an interface 4 | struct Z: StringBuffer {} 5 | 6 | void main() { 7 | var z = Z(); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/interface-impl-decl-success-generic-param.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | interface X { 4 | void foo(); 5 | } 6 | 7 | struct Z: T { 8 | void foo() {} 9 | } 10 | 11 | void main() { 12 | var z = Z(); 13 | } 14 | -------------------------------------------------------------------------------- /test/sema/invalid-argument-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | int foo(int a) { return a; } 4 | 5 | void main() { 6 | var f = false; 7 | // CHECK: [[@LINE+1]]:17: error: invalid argument #1 type 'bool' to 'foo', expected 'int' 8 | var z = foo(f); 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/invalid-arguments-to-function-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void f(void(int, int) a) { 4 | // CHECK: [[@LINE+1]]:11: error: invalid argument #2 type 'bool' to 'a', expected 'int' 5 | a(42, false); 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/invalid-break.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | for (var i in 0..1) { 5 | // CHECK-NOT: [[@LINE+1]]:9: error 6 | break; 7 | } 8 | if (false) { 9 | // CHECK: [[@LINE+1]]:9: error: 'break' is only allowed inside 'while', 'for', and 'switch' statements 10 | break; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/sema/invalid-operand-to-logical-not.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | var foo = 42; 5 | // CHECK: [[@LINE+1]]:10: error: type 'int' is not convertible to boolean 6 | if (!foo) { } 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/invalid-operands-to-logical-and.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | var foo = 0; 5 | var bar = true; 6 | // CHECK: [[@LINE+1]]:13: error: invalid operands 'int' and 'bool' to '&&' 7 | if (foo && bar) { } 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/invalid-operands-to-logical-or.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | var foo = false; 5 | var bar = 0; 6 | // CHECK: [[@LINE+1]]:13: error: invalid operands 'bool' and 'int' to '||' 7 | if (foo || bar) { } 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/lambda-capture-field.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct S { 4 | int d; 5 | 6 | void foo() { 7 | // CHECK: [[@LINE+1]]:43: error: unknown identifier 'd' 8 | var b = (int c, int a) -> c + a + d; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/lambda-capture-local-variable.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | var a = 1; 5 | // CHECK: [[@LINE+1]]:28: error: lambda capturing not implemented yet 6 | var b = (int c) -> c + a; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/lambda-capture-parameter.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void foo(int a) { 4 | var d = 3; 5 | // CHECK: [[@LINE+1]]:28: error: lambda capturing not implemented yet 6 | var b = (int c) -> c + a + d; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/lambda-infer-parameter-type-fail.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:13: error: couldn't infer type for parameter 'b' 5 | var a = b -> b; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/lambda-return-type-mismatch.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | var lambda = (int a, int b) -> { 5 | if (a > b) { 6 | return a + b 7 | } else { 8 | // CHECK: [[@LINE+1]]:13: error: mismatching return type 'bool', expected 'int' 9 | return false 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/sema/member-access-through-nullable-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s | %FileCheck %s 2 | 3 | struct Foo { 4 | int i; 5 | } 6 | 7 | void main() { 8 | Foo*? p = null; 9 | // CHECK: [[@LINE+1]]:13: warning: value may be null; unwrap it with a postfix '!' to silence this warning 10 | int i = p.i; 11 | } 12 | -------------------------------------------------------------------------------- /test/sema/member-function-call-through-nullable-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s | %FileCheck %s 2 | 3 | struct Foo: Copyable { 4 | int i; 5 | void bar() { } 6 | } 7 | 8 | void main() { 9 | Foo*? f = null; 10 | // CHECK: [[@LINE+1]]:5: warning: receiver may be null; unwrap it with a postfix '!' to silence this warning 11 | f.bar(); 12 | } 13 | -------------------------------------------------------------------------------- /test/sema/member-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | struct Foo { 4 | int i; 5 | void bar() { Foo* f = this; } 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/mismatching-argument-label-constructor.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct X: Copyable { 4 | X(int a) { } 5 | } 6 | 7 | void main() { 8 | // CHECK: [[@LINE+1]]:15: error: invalid argument name 'bar' for parameter 'a' 9 | var x = X(bar: 5); 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/mismatching-argument-label.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | int f(int foo, bool bar) { return foo; } 4 | 5 | int main() { 6 | // CHECK: [[@LINE+1]]:22: error: invalid argument name 'qux' for parameter 'bar' 7 | return f(foo: 5, qux: false); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/mismatching-binary-operands.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:17: error: invalid operands 'int' and 'bool' to '+' 5 | var foo = 4 + false; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/mismatching-switch-case-value-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | switch (1) { 5 | // CHECK: [[@LINE+1]]:14: error: case value type 'bool' doesn't match switch condition type 'int' 6 | case false: break; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/missing-member-assignment-in-constructor.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s | %FileCheck %s 2 | 3 | struct A { 4 | int i; 5 | int* j; 6 | 7 | // CHECK: [[@LINE+2]]:5: warning: constructor doesn't initialize member variable 'i' 8 | // CHECK: [[@LINE+1]]:5: warning: constructor doesn't initialize member variable 'j' 9 | A() {} 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/missing-return-false-positive-1.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -print-llvm %s 2 | 3 | int foo(bool b) { 4 | if (b) { 5 | return 1; 6 | } else { 7 | return 2; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/missing-return-false-positive-2.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -print-llvm %s 2 | 3 | int foo(int i) { 4 | switch (i) { 5 | case 5: return 2; 6 | default: return 3; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/missing-return.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:5: error: 'foo' is missing a return statement 4 | int foo(bool b) { 5 | if (b) { 6 | return 42; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/mixed-types-in-array-literal.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:23: error: mixed element types in array literal (expected 'int', found 'null') 5 | var a = [1, 2, 3, null]; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/move-local.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | struct Foo { } 4 | 5 | void main() { 6 | Foo f = undefined; 7 | Foo f2 = f; 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/moved-in-if-branch.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | struct S {} 4 | 5 | void bar(S s) {} 6 | void baz(S s) {} 7 | 8 | void foo(bool b, S s) { 9 | if (b) { 10 | bar(s); 11 | } else { 12 | baz(s); 13 | } 14 | 15 | bar(s); // TODO: Should warn about 's' being moved 16 | } 17 | -------------------------------------------------------------------------------- /test/sema/moved-variable-in-generic-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | struct A {} 4 | 5 | void f() { 6 | var t = T(); 7 | var a = t; 8 | } 9 | 10 | void g(T t) { 11 | var a = t; 12 | } 13 | 14 | void main() { 15 | f(); 16 | f(); 17 | g(A()); 18 | g(A()); 19 | } 20 | -------------------------------------------------------------------------------- /test/sema/multifile-error.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %p/inputs/multifile-error/a.cx %p/inputs/multifile-error/b.cx | %FileCheck -match-full-lines -strict-whitespace %p/inputs/multifile-error/b.cx 2 | -------------------------------------------------------------------------------- /test/sema/negated-int-literal-argument-overflow.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void foo(uint a) { } 4 | 5 | void main() { 6 | // CHECK: [[@LINE+1]]:9: error: -1 is out of range for type 'uint' 7 | foo(-1); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/negative-uint64-literal.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:16: error: -42 is out of range for type 'uint64' 5 | uint64 a = -42 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/non-bool-if-condition.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:9: error: type 'int' is not convertible to boolean 5 | if (0) {} 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/nonexisting-member-access.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct Foo { 4 | int qux; 5 | } 6 | 7 | void main() { 8 | var foo = Foo(1); 9 | // CHECK: [[@LINE+1]]:19: error: no member named 'bar' in 'Foo' 10 | var bar = foo.bar; 11 | } 12 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-extra-unwrap-early-exit.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s | %FileCheck %s 2 | 3 | void foo(int*? p) { 4 | if (p == null) { 5 | return; 6 | } 7 | defer println("foo"); 8 | // CHECK: [[@LINE+1]]:16: warning: value cannot be null here; null check can be removed 9 | var a = *(p!); 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-extra-unwrap-in-member-access.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s | %FileCheck %s 2 | 3 | struct S { 4 | S*? a; 5 | } 6 | 7 | void foo(S* p) { 8 | if (p.a != null) { 9 | // CHECK: [[@LINE+1]]:12: warning: value cannot be null here; null check can be removed 10 | p.a!.a = p; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-fail-member-access.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s -Wno-unused | %FileCheck %s 2 | 3 | struct S { 4 | int*? i; 5 | } 6 | 7 | void foo(S* p) { 8 | if (p.i != null) { 9 | p.i = null; 10 | // CHECK: [[@LINE+1]]:9: warning: dereferenced pointer may be null; unwrap it with a postfix '!' to silence this warning 11 | *p.i = 1; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-implicit-else-branch.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck -Werror -Wno-unused %s 2 | 3 | void foo(int*? p) { 4 | if (!p) { 5 | } else { 6 | var i = *p; 7 | *p = 42; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-implicit-then-branch.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck -Werror -Wno-unused %s 2 | 3 | void foo(int*? p) { 4 | if (p) { 5 | var i = *p; 6 | *p = 42; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-success-early-exit-local-variable.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s | %FileCheck %s 2 | 3 | void foo(int*? a) { 4 | int*? p = a; 5 | 6 | if (p == null) { 7 | return; 8 | } 9 | 10 | var i = *p; 11 | } 12 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-success-early-exit.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck -Werror -Wno-unused %s 2 | 3 | void foo(int*? p) { 4 | if (p == null) { 5 | return; 6 | } 7 | var a = *p; 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-success-else-branch.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck -Werror -Wno-unused %s 2 | 3 | void foo(int*? p) { 4 | if (p == null) { 5 | } else { 6 | var i = *p; 7 | *p = 42; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-success-from-another-variable.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck -Werror -Wno-unused %s 2 | 3 | void foo(int*? p) { 4 | if (p != null) { 5 | var j = p; 6 | var i = j; 7 | *i = 3; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-success-logical-or.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck -Werror -Wno-unused %s 2 | 3 | struct S { 4 | string x; 5 | } 6 | 7 | void foo(string n, S*? p) { 8 | while (p) { 9 | if (p.x == "x" || p.x == "y") 10 | continue; 11 | 12 | var r = n + '/' + p.x; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-success-member-access.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck -Werror -Wno-unused %s 2 | 3 | struct S { 4 | int*? i; 5 | } 6 | 7 | void foo(S* p) { 8 | if (p.i != null) { 9 | *p.i = 1; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-success-method.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck -Werror -Wno-unused %s 2 | 3 | struct S { 4 | void f() {} 5 | } 6 | 7 | void foo(S*? a) { 8 | var p = a; 9 | if (p != null) { 10 | p.f(); 11 | } 12 | if (a == null) { 13 | } else { 14 | a.f(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-success-previously-unwrapped.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck -Werror -Wno-unused %s 2 | 3 | void foo(int*? p) { 4 | *(p!) = 0; 5 | *p = 1; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-success-reassigned-unwrapped-value.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck -Werror -Wno-unused %s 2 | 3 | struct S { 4 | S*? a; 5 | S*? b; 6 | } 7 | 8 | void foo(S* s) { 9 | var a = s; 10 | var b = a.a!; 11 | a.a = s.b; 12 | 13 | if (a.a != null) { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/sema/null-check-analysis/null-check-success-then-branch.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck -Werror -Wno-unused %s 2 | 3 | void foo(int*? p) { 4 | if (p != null) { 5 | var i = *p; 6 | *p = 42; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/null-unsized-array-reference-cast.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | uint64[]? a = null 5 | // CHECK: [[@LINE+1]]:9: error: illegal cast from 'ArrayRef?' to 'void*?' 6 | _ = cast(a) 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/parameter-shadows-global-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void bar() {} 4 | void foo(int bar) { 5 | // TODO: Should call bar(). 6 | // CHECK: [[@LINE+1]]:5: error: 'bar' is not a function 7 | bar(); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/pointer-equals-incompatible-pointee-types.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void f(int* a, uint* b) { 4 | // CHECK: [[@LINE+1]]:7: error: comparison of distinct pointer types ('int*' and 'uint*') 5 | a == b; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/pointer-invalid-binary-op.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s -Wno-unused | %FileCheck %s 2 | 3 | void main() { 4 | int a = 2; 5 | int b = 3; 6 | int* p = &a; 7 | int* q = &b; 8 | // CHECK: [[@LINE+1]]:15: error: invalid operands 'int*' and 'int*' to '*' 9 | int c = p * q; 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/pointer-to-pointer-auto-dereference.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s -Wno-unused | %FileCheck %s 2 | 3 | extern void f(int* i); 4 | 5 | void a(int* p) { 6 | var q = p; 7 | // CHECK: [[@LINE+1]]:7: error: invalid argument #1 type 'int**' to 'f', expected 'int*' 8 | f(&q); 9 | // CHECK: [[@LINE+1]]:7: error: invalid argument #1 type 'int**' to 'f', expected 'int*' 10 | f(&p); 11 | } 12 | -------------------------------------------------------------------------------- /test/sema/pointer-to-rvalue-assign.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | int foo() { return 42; } 4 | 5 | void main() { 6 | int*? p = null; 7 | // CHECK: [[@LINE+1]]:7: error: cannot assign 'int' to 'int*?' 8 | p = foo(); 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/pointer-to-rvalue-return.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s -Wno-unused | %FileCheck %s 2 | 3 | // CHECK: [[@LINE+1]]:14: error: mismatching return type 'int', expected 'int*' 4 | int* foo() { return 42; } 5 | -------------------------------------------------------------------------------- /test/sema/pointer-to-rvalue.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | int foo() { return 42; } 4 | 5 | void main() { 6 | // CHECK: [[@LINE+1]]:17: error: cannot assign 'int' to 'int*' 7 | int* p = foo(); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/prefer-exact-param-type-match-if-ambiguous.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 0 %cx run %s 2 | 3 | int foo(T t) { 4 | return 1; 5 | } 6 | 7 | int foo(int i) { 8 | return 0; 9 | } 10 | 11 | int bar(T t) { 12 | t.x(); 13 | return 1; 14 | } 15 | 16 | int bar(int i) { 17 | return 0; 18 | } 19 | 20 | int main() { 21 | return foo(1) + bar(1); 22 | } 23 | -------------------------------------------------------------------------------- /test/sema/prefer-stdlib-if-ambiguous.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | import "stdlib.h" 4 | 5 | int main() { 6 | return abs(-42) 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/private-enum/a.cx: -------------------------------------------------------------------------------- 1 | // RUN: true 2 | 3 | // CHECK-NOT: a.cx:{{[0-9]+}}:{{[0-9]+}}: {{(warning|error)}}: 'A' is private 4 | 5 | private enum A { B, C } 6 | 7 | void f() { 8 | A a = A.C; 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/private-enum/private-enum.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s %p/a.cx | %FileCheck %s 2 | // RUN: %cx -typecheck %s %p/a.cx | %FileCheck %p/a.cx 3 | 4 | void main() { 5 | // CHECK: private-enum.cx:[[@LINE+1]]:13: warning: 'A' is private 6 | var b = A.B; 7 | 8 | // CHECK: private-enum.cx:[[@LINE+1]]:5: warning: 'A' is private 9 | A c = undefined; 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/private-global-function/a.cx: -------------------------------------------------------------------------------- 1 | // RUN: true 2 | 3 | private void f() {} 4 | 5 | void g() { 6 | // CHECK-NOT: a.cx:{{[0-9]+}}:{{[0-9]+}}: {{(warning|error)}}: '{{(f|g)}}' is private 7 | f(); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/private-global-function/private-global-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s %p/a.cx | %FileCheck %s 2 | // RUN: %cx -typecheck %s %p/a.cx | %FileCheck %p/a.cx 3 | 4 | void main() { 5 | // CHECK-NOT: 'g' is private 6 | g(); 7 | // CHECK: private-global-function.cx:[[@LINE+1]]:5: warning: 'f' is private 8 | f(); 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/private-global-variable/a.cx: -------------------------------------------------------------------------------- 1 | // RUN: true 2 | 3 | private var i = 6; 4 | 5 | void f() { 6 | // CHECK-NOT: a.cx:{{[0-9]+}}:{{[0-9]+}}: {{(warning|error)}}: 'i' is private 7 | i++; 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/private-global-variable/private-global-variable.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s %p/a.cx | %FileCheck %s 2 | // RUN: %cx -typecheck %s %p/a.cx | %FileCheck %p/a.cx 3 | 4 | void main() { 5 | // CHECK: [[@LINE+1]]:5: warning: 'i' is private 6 | i++; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/private-interface-member.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s | %FileCheck %s 2 | 3 | interface B { 4 | // CHECK: [[@LINE+1]]:5: warning: interface members cannot be private 5 | private void b(); 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/private-member-function/a.cx: -------------------------------------------------------------------------------- 1 | // RUN: true 2 | 3 | // CHECK-NOT: a.cx:{{[0-9]+}}:{{[0-9]+}}: {{(warning|error)}}: '{{(f|A\.f)}}' is private 4 | 5 | struct A { 6 | private void f() {} 7 | void g() { 8 | this.f(); 9 | f(); 10 | } 11 | } 12 | 13 | void g() { 14 | var a = A(); 15 | a.g(); 16 | } 17 | -------------------------------------------------------------------------------- /test/sema/private-member-function/private-member-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s %p/a.cx | %FileCheck %s 2 | // RUN: %cx -typecheck %s %p/a.cx | %FileCheck %p/a.cx 3 | 4 | void main() { 5 | var a = A(); 6 | // CHECK: [[@LINE+1]]:7: warning: 'f' is private 7 | a.f(); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/private-member-variable/a.cx: -------------------------------------------------------------------------------- 1 | // RUN: true 2 | 3 | // CHECK-NOT: a.cx:{{[0-9]+}}:{{[0-9]+}}: {{(warning|error)}}: '{{(a|A\.a)}}' is private 4 | 5 | struct A { 6 | private int a; 7 | A() {} 8 | void f() { 9 | this.a++; 10 | a++; 11 | } 12 | } 13 | 14 | void f() { 15 | var a = A(); 16 | a.a++; 17 | } 18 | -------------------------------------------------------------------------------- /test/sema/private-member-variable/private-member-variable.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s %p/a.cx | %FileCheck %s 2 | // RUN: %cx -typecheck %s %p/a.cx | %FileCheck %p/a.cx 3 | 4 | void main() { 5 | var a = A(); 6 | // CHECK: [[@LINE+1]]:7: warning: 'a' is private 7 | a.a++; 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/report-multiple-errors.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:13: error: unknown identifier 'ff' 5 | var a = ff; 6 | // CHECK: [[@LINE+1]]:13: error: unknown identifier 'xx' 7 | var b = xx; 8 | // CHECK-NOT: unknown identifier 'b' 9 | var c = b; 10 | } 11 | -------------------------------------------------------------------------------- /test/sema/resolve-generic-parameter-preserve-mutability.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | struct S: Copyable { 4 | void f(T t) { 5 | T*? p = null; 6 | *p! = t; 7 | } 8 | } 9 | 10 | void main() { 11 | var s = S(); 12 | s.f(1); 13 | } 14 | -------------------------------------------------------------------------------- /test/sema/return-array-with-wrong-size.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | int[1] foo() { 4 | int[2] buffer = undefined; 5 | // CHECK: [[@LINE+1]]:5: error: mismatching return type 'int[2]', expected 'int[1]' 6 | return buffer; 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/return-no-value-in-non-void-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | int foo() { 4 | // CHECK: [[@LINE+1]]:5: error: expected return statement to return a value of type 'int' 5 | return; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/return-result-of-generic-func.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | T qux(T t) { 4 | if (t < 0) { return -t; } 5 | return t; 6 | } 7 | int main() { 8 | return qux(-35); 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/return-value-in-void-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void foo(int a, int b) { 4 | // CHECK: [[@LINE+1]]:5: error: mismatching return type 'int', expected 'void' 5 | return a * b; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/sizeof-variable.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | var a = [1,2,3] 5 | // CHECK: [[@LINE+1]]:20: error: 'a' is not a type 6 | var s = sizeof(a) 7 | // CHECK: [[@LINE+1]]:20: error: 'a' is not a type 8 | var e = sizeof(a[0]) 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/stdlib-ambigous-reference-false-positive/a.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | import "a.h" 4 | 5 | void main() { 6 | var a = List() 7 | a.push(1) 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/stdlib-ambigous-reference-false-positive/a.h: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /test/sema/switch-mutable-condition.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | void main() { 4 | var i = 5 5 | 6 | switch (i) { 7 | case 5: return 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/template-not-unused.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck -Werror %s | %FileCheck %s -allow-empty 2 | 3 | void f() {} 4 | 5 | struct A {} 6 | 7 | void main() { 8 | f(); 9 | var a = A(); 10 | } 11 | 12 | // CHECK-NOT: unused 13 | -------------------------------------------------------------------------------- /test/sema/too-few-arguments.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | int sum(int a, int b) { return a + b; } 4 | 5 | // CHECK: [[@LINE+1]]:25: error: too few arguments to 'sum', expected 2 6 | void main() { var foo = sum(1); } 7 | -------------------------------------------------------------------------------- /test/sema/too-few-generic-arguments.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | T foo(T a, U b) { return a; } 4 | 5 | // CHECK: [[@LINE+3]]:31: error: too few generic arguments to 'foo', expected 2 6 | // CHECK: [[@LINE+2]]:23: error: no matching function 'foo(int, int)' 7 | // CHECK: :3:3: note: candidate function: 8 | void main() { var f = foo(1, 2); } 9 | -------------------------------------------------------------------------------- /test/sema/too-many-arguments.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | int sum(int a, int b) { return a + b; } 4 | 5 | // CHECK: [[@LINE+1]]:25: error: too many arguments to 'sum', expected 2 6 | void main() { var foo = sum(1, 2, 3); } 7 | -------------------------------------------------------------------------------- /test/sema/too-many-generic-arguments-on-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct C {} 4 | 5 | void main() { 6 | // CHECK: [[@LINE+1]]:15: error: too many generic arguments to 'C', expected 0 7 | _ = C(); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/too-many-generic-arguments.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | T foo(T a, T b) { return b; } 4 | 5 | // CHECK: [[@LINE+3]]:36: error: too many generic arguments to 'foo', expected 1 6 | // CHECK: [[@LINE+2]]:23: error: no matching function 'foo(int, int)' 7 | // CHECK: :3:3: note: candidate function: 8 | void main() { var f = foo(1, 2); } 9 | -------------------------------------------------------------------------------- /test/sema/tuple-equality.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:12: error: no matching operator '==' with arguments '(int a)' and '(int a)' 5 | (a: 1) == (a: 1); // TODO: Implement tuple equality comparison 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/tuple-mismatching-element-name-inferred.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | (int a, int b) f() { 4 | var a = 0; 5 | var c = 0; 6 | // CHECK: [[@LINE+1]]:5: error: mismatching return type '(int a, int c)', expected '(int a, int b)' 7 | return (a, c); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/tuple-mismatching-element-name.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | (int a, int b) f() { 4 | // CHECK: [[@LINE+1]]:5: error: mismatching return type '(int a, int c)', expected '(int a, int b)' 5 | return (a: 0, c: 0); 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/unknown-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | int fooz() { return 42; } 4 | 5 | // CHECK: [[@LINE+1]]:23: error: unknown identifier 'foo' 6 | void main() { var i = foo(); } 7 | -------------------------------------------------------------------------------- /test/sema/unknown-identifier-in-generic-type-member-func.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct S: Copyable { 4 | void foo() { 5 | // CHECK: [[@LINE+1]]:9: error: unknown identifier 'x' 6 | x++ 7 | } 8 | } 9 | 10 | void bar(S s) { 11 | s.foo() 12 | } 13 | -------------------------------------------------------------------------------- /test/sema/unknown-member-access-base.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:15: error: unknown identifier 'foo' 5 | var bar = foo.bar; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/unknown-variable.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:15: error: unknown identifier 'unknown' 5 | var foo = unknown; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/unnecessary-builtin-conversion.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s | %FileCheck %s 2 | 3 | void a(int i) { 4 | // CHECK: [[@LINE+1]]:13: warning: unnecessary conversion to same type 5 | var j = int(i); 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/unsupported-member-access.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | struct Foo {} 4 | 5 | void main() { 6 | // CHECK: [[@LINE+1]]:19: error: no member named 'bar' in 'Foo' 7 | var bar = Foo.bar; 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/unsupported-subscript.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | extern void*? f(); 4 | 5 | void main() { 6 | var p = cast(f()); 7 | // CHECK: [[@LINE+1]]:6: error: 'uint8*?' doesn't provide an index operator 8 | p[0] = 64; 9 | } 10 | -------------------------------------------------------------------------------- /test/sema/untyped-null.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:9: error: couldn't infer type of 'foo', add a type annotation 5 | var foo = null; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/use-imported-name-in-generic-func/inputs/header.h: -------------------------------------------------------------------------------- 1 | void foo(); 2 | -------------------------------------------------------------------------------- /test/sema/use-imported-name-in-generic-func/inputs/module.cx: -------------------------------------------------------------------------------- 1 | import "header.h" 2 | 3 | struct A: Copyable { 4 | A() { 5 | foo() 6 | } 7 | 8 | ~A() { 9 | foo() 10 | } 11 | 12 | void f() { 13 | foo() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/sema/use-imported-name-in-generic-func/main.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | import inputs 4 | 5 | void main() { 6 | A().f() 7 | } 8 | -------------------------------------------------------------------------------- /test/sema/variable-redefinition.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | var foo = 1; 5 | // CHECK: [[@LINE+2]]:9: error: redefinition of 'foo' 6 | // CHECK: :4:9: note: previous definition here 7 | var foo = 2; 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/variable-without-initializer.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s | %FileCheck %s 2 | 3 | void main() { 4 | // CHECK: [[@LINE+1]]:12: warning: missing initializer 5 | int*** i; 6 | } 7 | -------------------------------------------------------------------------------- /test/sema/variadic-function-too-few-args.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx -typecheck %s | %FileCheck %s 2 | 3 | extern void f(char* p, ...); 4 | 5 | void main() { 6 | // CHECK: [[@LINE+1]]:5: error: too few arguments to 'f', expected at least 1 7 | f(); 8 | } 9 | -------------------------------------------------------------------------------- /test/sema/void-return.cx: -------------------------------------------------------------------------------- 1 | // RUN: %cx -typecheck %s 2 | 3 | void foo() { 4 | return; 5 | } 6 | -------------------------------------------------------------------------------- /test/snapshot/allocas-in-multiple-constructors.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct S: Copyable { 4 | S() { 5 | var i = 4; 6 | } 7 | 8 | S(int foo) { 9 | var j = 5; 10 | } 11 | } 12 | 13 | void main() { 14 | var s = S(); 15 | var t = S(1); 16 | } 17 | -------------------------------------------------------------------------------- /test/snapshot/and-or.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | extern bool a(); 4 | extern bool b(); 5 | extern bool c(); 6 | 7 | void main() { 8 | var and = a() && b(); 9 | var and2 = a() && b() && c(); 10 | var or = a() || b(); 11 | var or2 = a() || b() || c(); 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/argument-auto-reference.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct Foo { int i; } 4 | void ptr(Foo* p) { } 5 | void main() { 6 | Foo f = undefined; 7 | ptr(f); 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/argument-auto-reference.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main3ptrEP3Foo(Foo* p) { 3 | return void 4 | } 5 | 6 | int main() { 7 | Foo* f = alloca Foo 8 | void _0 = call _EN4main3ptrEP3Foo(Foo* f) 9 | return int 0 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/argument-auto-reference.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %Foo = type { i32 } 3 | 4 | define void @_EN4main3ptrEP3Foo(%Foo* %p) { 5 | ret void 6 | } 7 | 8 | define i32 @main() { 9 | %f = alloca %Foo, align 8 10 | call void @_EN4main3ptrEP3Foo(%Foo* %f) 11 | ret i32 0 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/array-literal-non-constant-elements.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | int[2] f(int foo, int bar) { 4 | return [foo + bar, foo - bar]; 5 | } 6 | 7 | int[2] g(int foo, int bar) { 8 | var c = [foo + bar, foo - bar]; 9 | return c; 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/array-literal.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | int main() { 4 | var a = [1, 2, 3]; 5 | return a[1]; 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/array-literal.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | int[3]* a = alloca int[3] 4 | int[3] _0 = insertvalue int[3] undefined, 0, int 1 5 | int[3] _1 = insertvalue _0, 1, int 2 6 | int[3] _2 = insertvalue _1, 2, int 3 7 | store _2 to a 8 | int* _3 = getelementptr a, int 0, int 1 9 | int .load = load _3 10 | return .load 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/array-literal.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %a = alloca [3 x i32], align 4 4 | store [3 x i32] [i32 1, i32 2, i32 3], [3 x i32]* %a, align 4 5 | %1 = getelementptr inbounds [3 x i32], [3 x i32]* %a, i32 0, i32 1 6 | %.load = load i32, i32* %1, align 4 7 | ret i32 %.load 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/array-of-string-literals.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var a = ["foo", "bar"] 5 | } 6 | -------------------------------------------------------------------------------- /test/snapshot/array-pointer-auto-wrap.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | int[*] p = undefined; 5 | int[*]? o = p; 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/array-pointer-auto-wrap.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | int** p = alloca int* 4 | int** o = alloca int* 5 | int* p.load = load p 6 | store p.load to o 7 | return int 0 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/array-pointer-auto-wrap.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %p = alloca i32*, align 8 4 | %o = alloca i32*, align 8 5 | %p.load = load i32*, i32** %p, align 8 6 | store i32* %p.load, i32** %o, align 8 7 | ret i32 0 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/array-ref-auto-reference.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void foo(int[] a) {} 4 | 5 | void main() { 6 | var a = [1, 2, 3]; 7 | foo(a); 8 | baz(a); 9 | } 10 | 11 | void baz(int[3]* b) {} 12 | -------------------------------------------------------------------------------- /test/snapshot/array-ref-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | void foo(int[]* a) {} 4 | -------------------------------------------------------------------------------- /test/snapshot/array-ref-pointer.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main3fooEP8ArrayRefI3intE(ArrayRef* a) { 3 | return void 4 | } 5 | -------------------------------------------------------------------------------- /test/snapshot/array-ref-pointer.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %"ArrayRef" = type { i32*, i32 } 3 | 4 | define void @_EN4main3fooEP8ArrayRefI3intE(%"ArrayRef"* %a) { 5 | ret void 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/asm-label-attribute.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | import "./asm-label-attribute.h"; 4 | 5 | void main() { 6 | FOO(); 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/asm-label-attribute.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | void _0 = call test() 4 | return int 0 5 | } 6 | 7 | extern void test() 8 | -------------------------------------------------------------------------------- /test/snapshot/asm-label-attribute.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | call void @"\01test"() 4 | ret i32 0 5 | } 6 | 7 | declare void @"\01test"() 8 | -------------------------------------------------------------------------------- /test/snapshot/asm-label-attribute.h: -------------------------------------------------------------------------------- 1 | void FOO() asm("test"); 2 | -------------------------------------------------------------------------------- /test/snapshot/assert.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | extern bool b(); 4 | 5 | void main() { 6 | assert(b()); 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/assign-undefined-in-constructor.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct A { 4 | int i; 5 | 6 | A() { 7 | i = undefined; 8 | } 9 | } 10 | 11 | void main() { 12 | var a = A(); 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/assign-undefined-in-constructor.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | A* a = alloca A 4 | void _0 = call _EN4main1A4initE(A* a) 5 | return int 0 6 | } 7 | 8 | void _EN4main1A4initE(A* this) { 9 | return void 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/assign-undefined-in-constructor.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %A = type { i32 } 3 | 4 | define i32 @main() { 5 | %a = alloca %A, align 8 6 | call void @_EN4main1A4initE(%A* %a) 7 | ret i32 0 8 | } 9 | 10 | define void @_EN4main1A4initE(%A* %this) { 11 | ret void 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/assignment.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var foo = 0; 5 | foo--; 6 | foo = 666; 7 | foo++; 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/assignment.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | int* foo = alloca int 4 | store int 0 to foo 5 | int foo.load = load foo 6 | int _0 = foo.load + int -1 7 | store _0 to foo 8 | store int 666 to foo 9 | int foo.load_0 = load foo 10 | int _1 = foo.load_0 + int 1 11 | store _1 to foo 12 | return int 0 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/auto-convert-array-literal-elements.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | float[1] foo = [1.0]; 5 | uint16[2] bar = [50, 100]; 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/auto-convert-array-literal-elements.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | float[1]* foo = alloca float[1] 4 | uint16[2]* bar = alloca uint16[2] 5 | float[1] _0 = insertvalue float[1] undefined, 0, float 1 6 | store _0 to foo 7 | uint16[2] _1 = insertvalue uint16[2] undefined, 0, uint16 50 8 | uint16[2] _2 = insertvalue _1, 1, uint16 100 9 | store _2 to bar 10 | return int 0 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/auto-convert-array-literal-elements.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %foo = alloca [1 x float], align 4 4 | %bar = alloca [2 x i16], align 2 5 | store [1 x float] [float 1.000000e+00], [1 x float]* %foo, align 4 6 | store [2 x i16] [i16 50, i16 100], [2 x i16]* %bar, align 2 7 | ret i32 0 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/auto-convert-literals-in-ternary.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | uint8 foo(bool b) { 4 | return b ? 0xFF : 0xEE; 5 | } 6 | -------------------------------------------------------------------------------- /test/snapshot/auto-convert-literals-in-ternary.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | uint8 _EN4main3fooE4bool(bool b) { 3 | br b, if.then, if.else 4 | 5 | if.then: 6 | br if.end(uint8 255) 7 | 8 | if.else: 9 | br if.end(uint8 238) 10 | 11 | if.end(uint8 if.result): 12 | return if.result 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/auto-deref-arithmetic.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | int a = 0; 5 | int* p = a; 6 | a += p; 7 | a = a * p; 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/auto-deref-subscript-result.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | struct S { 4 | T t; 5 | 6 | T* operator[](int i) { 7 | return t; 8 | } 9 | } 10 | 11 | void f(S* s) { 12 | s[0]++; 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/auto-deref-subscript-result.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main1fEP1SI3intE(S* s) { 3 | int* _0 = call _EN4main1SI3intEixE3int(S* s, int 0) 4 | int .load = load _0 5 | int _1 = .load + int 1 6 | store _1 to _0 7 | return void 8 | } 9 | 10 | int* _EN4main1SI3intEixE3int(S* this, int i) { 11 | int* t = getelementptr this, 0 12 | return t 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/auto-generated-move-constructor.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | struct X { 4 | int i; 5 | ~X() {} 6 | } 7 | 8 | void foo(X* p, X x) { 9 | p.init(x); 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/auto-generated-move-constructor.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main3fooEP1X1X(X* p, X x) { 3 | store x to p 4 | return void 5 | } 6 | 7 | void _EN4main1X6deinitE(X* this) { 8 | return void 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/auto-generated-move-constructor.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %X = type { i32 } 3 | 4 | define void @_EN4main3fooEP1X1X(%X* %p, %X %x) { 5 | store %X %x, %X* %p, align 4 6 | ret void 7 | } 8 | 9 | define void @_EN4main1X6deinitE(%X* %this) { 10 | ret void 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/bitwise-operators.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main(int a, int b, uint c, uint d) { 4 | _ = a & b; 5 | _ = a | b; 6 | _ = a ^ b; 7 | _ = a << b; 8 | _ = a >> b; 9 | _ = c >> d; 10 | _ = ~a; 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/bitwise-operators.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main(int a, int b, uint c, uint d) { 3 | int _0 = a & b 4 | int _1 = a | b 5 | int _2 = a ^ b 6 | int _3 = a << b 7 | int _4 = a >> b 8 | uint _5 = c >> d 9 | bool _6 = !a 10 | return int 0 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/bitwise-operators.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main(i32 %a, i32 %b, i32 %c, i32 %d) { 3 | %1 = and i32 %a, %b 4 | %2 = or i32 %a, %b 5 | %3 = xor i32 %a, %b 6 | %4 = shl i32 %a, %b 7 | %5 = ashr i32 %a, %b 8 | %6 = lshr i32 %c, %d 9 | %7 = xor i32 %a, -1 10 | ret i32 0 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/boolean-literal.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var b = false; 5 | var c = b == true; 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/boolean-literal.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | bool* b = alloca bool 4 | bool* c = alloca bool 5 | store bool false to b 6 | bool b.load = load b 7 | bool _0 = b.load == bool true 8 | store _0 to c 9 | return int 0 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/boolean-literal.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %b = alloca i1, align 1 4 | %c = alloca i1, align 1 5 | store i1 false, i1* %b, align 1 6 | %b.load = load i1, i1* %b, align 1 7 | %1 = icmp eq i1 %b.load, true 8 | store i1 %1, i1* %c, align 1 9 | ret i32 0 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/box.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var p = Box(Box(42)); 5 | var q = Box(42); 6 | var r = Box(42); 7 | *q.get() = 0; 8 | r.get(); 9 | q = r; 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/break.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | while (true) { 5 | if (true) { 6 | break; 7 | var a = 1; 8 | } 9 | break; 10 | } 11 | switch (1) { 12 | default: 13 | break; 14 | var b = 1; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/snapshot/bug-with-destructor-call-codegen.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct X { 4 | ~X() {} 5 | } 6 | 7 | struct Y { 8 | int f() { 9 | return 1; 10 | } 11 | } 12 | 13 | void main() { 14 | var a = X(); 15 | Y().f(); 16 | } 17 | -------------------------------------------------------------------------------- /test/snapshot/builtin-type-auto-reference.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void foo(int* ref_i) { } 4 | 5 | void main() { 6 | var bar = 42; 7 | foo(bar); 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/builtin-type-auto-reference.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main3fooEP3int(int* ref_i) { 3 | return void 4 | } 5 | 6 | int main() { 7 | int* bar = alloca int 8 | store int 42 to bar 9 | void _0 = call _EN4main3fooEP3int(int* bar) 10 | return int 0 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/builtin-type-auto-reference.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define void @_EN4main3fooEP3int(i32* %ref_i) { 3 | ret void 4 | } 5 | 6 | define i32 @main() { 7 | %bar = alloca i32, align 4 8 | store i32 42, i32* %bar, align 4 9 | call void @_EN4main3fooEP3int(i32* %bar) 10 | ret i32 0 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/c-callback-function/c-callback-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | import "c-callback-function.h"; 4 | 5 | int f(int a) { 6 | return a; 7 | } 8 | 9 | void main() { 10 | foo(f); 11 | bar(f); 12 | baz(f); 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/c-callback-function/c-callback-function.h: -------------------------------------------------------------------------------- 1 | typedef int(*pcallback)(int); 2 | typedef int(callback)(int); 3 | 4 | void foo(pcallback cb); 5 | void bar(callback* cb); 6 | void baz(int(*cb)(int)); 7 | -------------------------------------------------------------------------------- /test/snapshot/c-strings.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct S { 4 | char[1024] a; 5 | } 6 | 7 | void main() { 8 | S s = undefined; 9 | s.a == "x"; 10 | StringBuffer("x") != s.a; 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/compare-nullable-and-nonnull-ptrs.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | void f(int* foo, int*? bar) { 4 | if (foo == bar) {} 5 | } 6 | -------------------------------------------------------------------------------- /test/snapshot/compare-nullable-and-nonnull-ptrs.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main1fEP3intOP3int(int* foo, int* bar) { 3 | bool _0 = foo == bar 4 | br _0, if.then, if.else 5 | 6 | if.then: 7 | br if.end 8 | 9 | if.else: 10 | br if.end 11 | 12 | if.end: 13 | return void 14 | } 15 | -------------------------------------------------------------------------------- /test/snapshot/compare-pointer-to-integer.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | void f(int* foo, int bar) { 4 | _ = foo < bar; 5 | } 6 | -------------------------------------------------------------------------------- /test/snapshot/compare-pointer-to-integer.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main1fEP3int3int(int* foo, int bar) { 3 | int foo.load = load foo 4 | bool _0 = foo.load < bar 5 | return void 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/compare-pointer-to-integer.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define void @_EN4main1fEP3int3int(i32* %foo, i32 %bar) { 3 | %foo.load = load i32, i32* %foo, align 4 4 | %1 = icmp slt i32 %foo.load, %bar 5 | ret void 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/compound-assignment-rhs-precedence.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | void f(float64* foo, float64 bar, float64 baz) { 4 | *foo *= 1.0 - bar * baz; 5 | } 6 | -------------------------------------------------------------------------------- /test/snapshot/compound-assignment-rhs-precedence.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main1fEP7float647float647float64(float64* foo, float64 bar, float64 baz) { 3 | float64 foo.load = load foo 4 | float64 _0 = bar * baz 5 | float64 _1 = float64 1 - _0 6 | float64 _2 = foo.load * _1 7 | store _2 to foo 8 | return void 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/compound-assignment-rhs-precedence.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define void @_EN4main1fEP7float647float647float64(double* %foo, double %bar, double %baz) { 3 | %foo.load = load double, double* %foo, align 8 4 | %1 = fmul double %bar, %baz 5 | %2 = fsub double 1.000000e+00, %1 6 | %3 = fmul double %foo.load, %2 7 | store double %3, double* %foo, align 8 8 | ret void 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/compound-assignment.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var i = 0; 5 | i += 1; 6 | i -= 1; 7 | i *= 1; 8 | i /= 1; 9 | i &= 1; 10 | i |= 1; 11 | i ^= 1; 12 | i <<= 1; 13 | i >>= 1; 14 | } 15 | -------------------------------------------------------------------------------- /test/snapshot/constant-macro.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | import "constant-macro.h" 4 | 5 | void foo(int i) { 6 | switch (i) { 7 | case FOO: return 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/constant-macro.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main3fooE3int(int i) { 3 | switch i { 4 | int 42 -> switch.case.0 5 | } 6 | 7 | switch.case.0: 8 | return void 9 | 10 | switch.default: 11 | br switch.end 12 | 13 | switch.end: 14 | return void 15 | } 16 | -------------------------------------------------------------------------------- /test/snapshot/constant-macro.h: -------------------------------------------------------------------------------- 1 | #define FOO 42 2 | -------------------------------------------------------------------------------- /test/snapshot/constructor-call-before-declaration.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var f = Foo(5); 5 | } 6 | 7 | struct Foo: Copyable { 8 | float f; 9 | Foo(int i) { f = 0.0; } 10 | ~Foo() { } 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/constructor-delegation.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var x = X(4, 2); 5 | } 6 | 7 | struct X { 8 | X(int a, int b) { 9 | init(a); 10 | } 11 | 12 | X(int a) { 13 | init(); 14 | } 15 | 16 | X() {} 17 | } 18 | -------------------------------------------------------------------------------- /test/snapshot/continue.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void baz(bool foo) { 4 | while (foo) { 5 | if (foo) { 6 | baz(foo); 7 | continue; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/conversion-to-bool.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -w 2 | 3 | void f(char* pb) { 4 | var b = bool(2); 5 | b = bool(*pb); 6 | bool(b); 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/conversion-to-bool.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main1fEP4char(char* pb) { 3 | bool* b = alloca bool 4 | bool _0 = cast int 2 to bool 5 | store _0 to b 6 | char pb.load = load pb 7 | bool _1 = cast pb.load to bool 8 | store _1 to b 9 | bool b.load = load b 10 | return void 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/conversion-to-bool.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define void @_EN4main1fEP4char(i8* %pb) { 3 | %b = alloca i1, align 1 4 | store i1 true, i1* %b, align 1 5 | %pb.load = load i8, i8* %pb, align 1 6 | %1 = icmp ne i8 %pb.load, 0 7 | store i1 %1, i1* %b, align 1 8 | %b.load = load i1, i1* %b, align 1 9 | ret void 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/copyable-empty-destructor.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct Foo: Copyable { 4 | ~Foo() { } 5 | } 6 | 7 | void main() { 8 | Foo foo = undefined; 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/copyable-empty-destructor.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | Foo* foo = alloca Foo 4 | void _0 = call _EN4main3Foo6deinitE(Foo* foo) 5 | return int 0 6 | } 7 | 8 | void _EN4main3Foo6deinitE(Foo* this) { 9 | return void 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/copyable-empty-destructor.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %Foo = type {} 3 | 4 | define i32 @main() { 5 | %foo = alloca %Foo, align 8 6 | call void @_EN4main3Foo6deinitE(%Foo* %foo) 7 | ret i32 0 8 | } 9 | 10 | define void @_EN4main3Foo6deinitE(%Foo* %this) { 11 | ret void 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/copyable-type-auto-reference.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct Foo: Copyable { int i; } 4 | 5 | void foo(Foo* ref_f) { } 6 | 7 | void main() { 8 | Foo f = undefined; 9 | foo(f); 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/copyable-type-auto-reference.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main3fooEP3Foo(Foo* ref_f) { 3 | return void 4 | } 5 | 6 | int main() { 7 | Foo* f = alloca Foo 8 | void _0 = call _EN4main3fooEP3Foo(Foo* f) 9 | return int 0 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/copyable-type-auto-reference.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %Foo = type { i32 } 3 | 4 | define void @_EN4main3fooEP3Foo(%Foo* %ref_f) { 5 | ret void 6 | } 7 | 8 | define i32 @main() { 9 | %f = alloca %Foo, align 8 10 | call void @_EN4main3fooEP3Foo(%Foo* %f) 11 | ret i32 0 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/copyable-type-definition.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct Foo: Copyable { 4 | int a; 5 | bool b; 6 | 7 | Foo(int a, bool b) { 8 | this.a = a; 9 | this.b = b; 10 | this.a++; 11 | } 12 | } 13 | 14 | void main() { 15 | var f = Foo(666, true); 16 | f.a++; 17 | var bar = f.a; 18 | var qux = f.b; 19 | } 20 | -------------------------------------------------------------------------------- /test/snapshot/copyable-type-member-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct Foo: Copyable { 4 | int baz; 5 | Foo() { this.baz = 42; } 6 | void bar() { } 7 | int qux() { return this.baz; } 8 | } 9 | 10 | void main() { 11 | var foo = Foo(); 12 | foo.bar(); 13 | var i = foo.qux(); 14 | } 15 | -------------------------------------------------------------------------------- /test/snapshot/copyable-type-member-pointer-access-without-dereference.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct S: Copyable { 4 | int* a 5 | 6 | void foo() { 7 | var b = a 8 | } 9 | } 10 | 11 | void main() { 12 | S(1).foo() 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/copyable-type-method-call-before-declaration.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots inputs/copyable-type-method-call-before-declaration/a.cx inputs/copyable-type-method-call-before-declaration/b.cx 2 | -------------------------------------------------------------------------------- /test/snapshot/copyable-type-method-call-before-declaration.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | B* _0 = alloca B 4 | void _1 = call _EN4main1B4initE(B* _0) 5 | void _2 = call _EN4main1B1fE(B* _0) 6 | return int 0 7 | } 8 | 9 | void _EN4main1B1fE(B* this) { 10 | return void 11 | } 12 | 13 | void _EN4main1B4initE(B* this) { 14 | return void 15 | } 16 | -------------------------------------------------------------------------------- /test/snapshot/copyable-type-method-call-before-declaration.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %B = type {} 3 | 4 | define i32 @main() { 5 | %1 = alloca %B, align 8 6 | call void @_EN4main1B4initE(%B* %1) 7 | call void @_EN4main1B1fE(%B* %1) 8 | ret i32 0 9 | } 10 | 11 | define void @_EN4main1B4initE(%B* %this) { 12 | ret void 13 | } 14 | 15 | define void @_EN4main1B1fE(%B* %this) { 16 | ret void 17 | } 18 | -------------------------------------------------------------------------------- /test/snapshot/copyable-type-mutate-this.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct S: Copyable { 4 | int i 5 | 6 | void s() { 7 | this.i = 2 8 | } 9 | } 10 | 11 | void main() { 12 | S(1).s() 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/copyable-type-mutating-function-member-access.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct S: Copyable { 4 | int a 5 | 6 | void foo() { 7 | var b = a 8 | } 9 | } 10 | 11 | void main() { 12 | S(1).foo() 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/discarding-assignment.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | extern int foo(); 4 | 5 | void main() { 6 | _ = foo(); 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/discarding-assignment.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | extern int foo() 3 | 4 | int main() { 5 | int _0 = call foo() 6 | return int 0 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/discarding-assignment.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | declare i32 @foo() 3 | 4 | define i32 @main() { 5 | %1 = call i32 @foo() 6 | ret i32 0 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/empty-composite-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct S: Copyable { } 4 | struct C { } 5 | 6 | void main() { 7 | S s = undefined; 8 | C c = undefined; 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/empty-composite-type.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | S* s = alloca S 4 | C* c = alloca C 5 | return int 0 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/empty-composite-type.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %S = type {} 3 | %C = type {} 4 | 5 | define i32 @main() { 6 | %s = alloca %S, align 8 7 | %c = alloca %C, align 8 8 | ret i32 0 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/empty-string-literal.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | int main() { 4 | return "".size() 5 | } 6 | -------------------------------------------------------------------------------- /test/snapshot/empty-string-literal.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | string* __str = alloca string 4 | void _0 = call _EN3std6string4initEP4char3int(string* __str, char* "", int 0) 5 | int _1 = call _EN3std6string4sizeE(string* __str) 6 | return _1 7 | } 8 | 9 | int _EN3std6string4sizeE(string* this) { 10 | } 11 | 12 | void _EN3std6string4initEP4char3int(string* this, char* pointer, int length) { 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/enum-typed-field.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | enum E { A } 4 | 5 | struct S { 6 | E e; 7 | E f; 8 | } 9 | 10 | E f(S s) { 11 | return s.f; 12 | } 13 | 14 | E g(S* s) { 15 | return s.f; 16 | } 17 | -------------------------------------------------------------------------------- /test/snapshot/enum-typed-field.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int _EN4main1fE1S(S s) { 3 | int f = extractvalue s, 1 4 | return f 5 | } 6 | 7 | int _EN4main1gEP1S(S* s) { 8 | int* f = getelementptr s, 1 9 | int f.load = load f 10 | return f.load 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/enum-typed-field.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %S = type { i32, i32 } 3 | 4 | define i32 @_EN4main1fE1S(%S %s) { 5 | %f = extractvalue %S %s, 1 6 | ret i32 %f 7 | } 8 | 9 | define i32 @_EN4main1gEP1S(%S* %s) { 10 | %f = getelementptr inbounds %S, %S* %s, i32 0, i32 1 11 | %f.load = load i32, i32* %f, align 4 12 | ret i32 %f.load 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/enum.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | var x = 0; 4 | 5 | enum A { x, y, z } 6 | 7 | void main() { 8 | var foo = A.z; 9 | if (foo == A.y) {} 10 | if (foo != A.x) {} 11 | switch (foo) { 12 | case A.x: return; 13 | case A.y: return; 14 | case A.z: return; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/snapshot/escape-character.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | _ = "\\n" 5 | } 6 | -------------------------------------------------------------------------------- /test/snapshot/escape-character.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | string* __str = alloca string 4 | void _0 = call _EN3std6string4initEP4char3int(string* __str, char* "\n", int 2) 5 | return int 0 6 | } 7 | 8 | void _EN3std6string4initEP4char3int(string* this, char* pointer, int length) { 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/exclusive-range-operator.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | int main() { 4 | var p = 9; 5 | 6 | for (var i in 0..3) { 7 | p -= i; 8 | } 9 | 10 | return p; 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/explicit-destructor-call.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | struct A { 4 | ~A() {} 5 | } 6 | 7 | void f(A* a) { 8 | a.deinit(); 9 | } 10 | 11 | struct B {} 12 | 13 | void g(B* b) { 14 | b.deinit(); 15 | } 16 | 17 | void h(char* c) { 18 | c.deinit(); 19 | } 20 | -------------------------------------------------------------------------------- /test/snapshot/explicit-destructor-call.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main1fEP1A(A* a) { 3 | void _0 = call _EN4main1A6deinitE(A* a) 4 | return void 5 | } 6 | 7 | void _EN4main1A6deinitE(A* this) { 8 | return void 9 | } 10 | 11 | void _EN4main1gEP1B(B* b) { 12 | return void 13 | } 14 | 15 | void _EN4main1hEP4char(char* c) { 16 | return void 17 | } 18 | -------------------------------------------------------------------------------- /test/snapshot/explicit-destructor-call.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %A = type {} 3 | %B = type {} 4 | 5 | define void @_EN4main1fEP1A(%A* %a) { 6 | call void @_EN4main1A6deinitE(%A* %a) 7 | ret void 8 | } 9 | 10 | define void @_EN4main1A6deinitE(%A* %this) { 11 | ret void 12 | } 13 | 14 | define void @_EN4main1gEP1B(%B* %b) { 15 | ret void 16 | } 17 | 18 | define void @_EN4main1hEP4char(i8* %c) { 19 | ret void 20 | } 21 | -------------------------------------------------------------------------------- /test/snapshot/field-default-value.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct Foo { 4 | int i = 42; 5 | } 6 | 7 | struct Bar { 8 | int i = 42; 9 | int j; 10 | } 11 | 12 | void main() { 13 | var foo = Foo(); 14 | var bar = Bar(j: -1); 15 | } 16 | -------------------------------------------------------------------------------- /test/snapshot/float-arithmetic.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var a = 1.0; 5 | var b = 2.0 * -a; 6 | b++; 7 | b--; 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/float-constant-auto-cast.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | const a = 4.0; 4 | 5 | float f(float b) { 6 | return b * (a * 2.0); 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/float-constant-auto-cast.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | float _EN4main1fE5float(float b) { 3 | float _0 = float 4 * float 2 4 | float _1 = b * _0 5 | return _1 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/float-constant-auto-cast.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define float @_EN4main1fE5float(float %b) { 3 | %1 = fmul float %b, 8.000000e+00 4 | ret float %1 5 | } 6 | -------------------------------------------------------------------------------- /test/snapshot/float-literal-auto-cast.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | float f = 42.0; 5 | float g = -42.0; 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/float-literal-auto-cast.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | float* f = alloca float 4 | float* g = alloca float 5 | store float 42 to f 6 | float _0 = -float 42 7 | store _0 to g 8 | return int 0 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/float-literal-auto-cast.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %f = alloca float, align 4 4 | %g = alloca float, align 4 5 | store float 4.200000e+01, float* %f, align 4 6 | store float -4.200000e+01, float* %g, align 4 7 | ret i32 0 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/foo.h: -------------------------------------------------------------------------------- 1 | struct Foo { 2 | signed bar; 3 | const char* baz; 4 | }; 5 | 6 | inline unsigned getBar(const struct Foo* foo) { 7 | return foo->bar; 8 | } 9 | 10 | typedef enum { 11 | MAGIC_NUMBER = 5 12 | } Qux; 13 | 14 | #define ANSWER 42 15 | -------------------------------------------------------------------------------- /test/snapshot/for-loop-c-style.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var sum = 0; 5 | for (int i = 3; i < 9; i++) { 6 | sum += i; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/for-loop-continue.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | for (var ch in "abc") { 5 | if (ch == 'b') { 6 | continue; 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/for-loop.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var sum = 0; 5 | for var i in 68...75 { 6 | sum += i; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/function-pointer-member-variable.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct X { 4 | int(int) p; 5 | 6 | void f() { 7 | this.p(42); 8 | p(42); 9 | var p2 = p; 10 | p2(42); 11 | } 12 | } 13 | 14 | int foo(int a) { 15 | return a; 16 | } 17 | 18 | void main() { 19 | var x = X(foo); 20 | x.p(42); 21 | x.f(); 22 | } 23 | -------------------------------------------------------------------------------- /test/snapshot/function-pointer-parameter.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void f() {} 4 | 5 | int f2(int a, bool b) { return a; } 6 | 7 | void g(void() p) { 8 | p(); 9 | } 10 | 11 | void g2(int(int, bool) p) { 12 | var a = p(42, !true) + 1; 13 | } 14 | 15 | void main() { 16 | g(f); 17 | g2(f2); 18 | } 19 | -------------------------------------------------------------------------------- /test/snapshot/function.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | bar(); 5 | foo(); 6 | } 7 | 8 | void foo() { } 9 | 10 | extern void bar(); 11 | -------------------------------------------------------------------------------- /test/snapshot/function.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | void _0 = call bar() 4 | void _1 = call _EN4main3fooE() 5 | return int 0 6 | } 7 | 8 | extern void bar() 9 | 10 | void _EN4main3fooE() { 11 | return void 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/function.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | call void @bar() 4 | call void @_EN4main3fooE() 5 | ret i32 0 6 | } 7 | 8 | declare void @bar() 9 | 10 | define void @_EN4main3fooE() { 11 | ret void 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/generic-arg-infer-conflict-skipped.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | void foo(T a, T b) { } 4 | int foo(T a, U b) { return 0; } 5 | 6 | void main() { foo(1, false) } 7 | -------------------------------------------------------------------------------- /test/snapshot/generic-arg-infer-conflict-skipped.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | int _0 = call _EN4main3fooI3int4boolEE3int4bool(int 1, bool false) 4 | return int 0 5 | } 6 | 7 | int _EN4main3fooI3int4boolEE3int4bool(int a, bool b) { 8 | return int 0 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/generic-arg-infer-conflict-skipped.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %1 = call i32 @_EN4main3fooI3int4boolEE3int4bool(i32 1, i1 false) 4 | ret i32 0 5 | } 6 | 7 | define i32 @_EN4main3fooI3int4boolEE3int4bool(i32 %a, i1 %b) { 8 | ret i32 0 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/generic-arg-infer-in-constructor-call.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct Foo { 4 | T t; 5 | 6 | Foo(T t) { this.t = t; } 7 | } 8 | 9 | void main() { 10 | var i = Foo(42); 11 | var b = Foo(""); 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/generic-argument-inference-deep.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | struct S: Copyable { 4 | T f; 5 | } 6 | 7 | bool operator==(S a, S b) { 8 | return true; 9 | } 10 | 11 | void f(S c, S d) { 12 | _ = c == d; 13 | } 14 | 15 | void f(S* c, S* d) { 16 | _ = *c == *d; 17 | } 18 | -------------------------------------------------------------------------------- /test/snapshot/generic-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void foo(T t) { } 4 | 5 | T bar(T t) { return t; } 6 | 7 | T qux(T t) { 8 | if (t < 0) { return -t; } 9 | return t; 10 | } 11 | 12 | void main() { 13 | foo(1); 14 | foo(false); 15 | foo(true); 16 | var b = bar("bar"); 17 | var five = qux(-5); 18 | } 19 | -------------------------------------------------------------------------------- /test/snapshot/generic-method-on-generic-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct X { 4 | void f(T(U) u) {} 5 | } 6 | 7 | int g(bool i) { return int(i); } 8 | 9 | void main() { 10 | var x = X(); 11 | x.f(g); 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/generic-method-use-return-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct X { 4 | X f(U u) { 5 | X x = undefined; 6 | return x; 7 | } 8 | 9 | void g() {} 10 | } 11 | 12 | void main(X x) { 13 | var a = x.f(false); 14 | a.g(); 15 | } 16 | -------------------------------------------------------------------------------- /test/snapshot/generic-method.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct X { 4 | T f(T() t) { 5 | return t(); 6 | } 7 | } 8 | 9 | int g() { return 0; } 10 | bool h() { return false; } 11 | 12 | void main() { 13 | var x = X(); 14 | x.f(g); 15 | x.f(h); 16 | } 17 | -------------------------------------------------------------------------------- /test/snapshot/generic-param-0-arg-constructor-call.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct C { 4 | int i; 5 | C() { i = 0; } 6 | } 7 | 8 | struct A { 9 | A() { 10 | var t = T(); 11 | } 12 | } 13 | 14 | void main() { 15 | var a = A(); 16 | } 17 | -------------------------------------------------------------------------------- /test/snapshot/generic-param-as-null-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct S: Copyable { 4 | T*? p 5 | 6 | S() { 7 | p = null 8 | } 9 | } 10 | 11 | void main() { 12 | _ = S() 13 | _ = S() 14 | } 15 | -------------------------------------------------------------------------------- /test/snapshot/generic-param-use-inside-method.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct S: Copyable { 4 | void f() { 5 | g(); 6 | T t = undefined; 7 | } 8 | 9 | void g() { 10 | T t2 = undefined; 11 | } 12 | } 13 | 14 | void main() { 15 | var s = S(); 16 | s.f(); 17 | } 18 | -------------------------------------------------------------------------------- /test/snapshot/generic-type-constructor-call-in-another-module.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Iinputs 2 | 3 | import imported_generic_type_constructor 4 | 5 | void main() { 6 | var a = A() 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/generic-type-constructor-call-in-another-module.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | A* a = alloca A 4 | void _0 = call _EN33imported_generic_type_constructor1AI3intE4initE(A* a) 5 | return int 0 6 | } 7 | 8 | void _EN33imported_generic_type_constructor1AI3intE4initE(A* this) { 9 | int** a = getelementptr this, 0 10 | store int* null to a 11 | return void 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/generic-type-destructor.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct C { 4 | ~C() { } 5 | } 6 | 7 | void main() { 8 | var i = C() 9 | var b = C() 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/generic-type-generic-param-in-constructor-params.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct M { 4 | M(T[] a) {} 5 | } 6 | 7 | void main() { 8 | var b = [1, 2, 3]; 9 | _ = M(b); 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/generic-type-member-func-using-generic-param-2.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct C: Copyable { 4 | void f() { 5 | g() 6 | } 7 | 8 | void g() { 9 | var a = sizeof(T) 10 | } 11 | } 12 | 13 | void main() { 14 | var c = C() 15 | c.f() 16 | } 17 | -------------------------------------------------------------------------------- /test/snapshot/generic-type-member-func-using-generic-param.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct A: Copyable { 4 | void a(E n) { } 5 | } 6 | 7 | void main() { 8 | var a = A() 9 | a.a(5) 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/generic-type-member-func.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct F: Copyable { 4 | T a 5 | U b 6 | F() { 7 | a = undefined 8 | b = undefined 9 | } 10 | void foo() { } 11 | void unused() { } 12 | } 13 | 14 | void main() { 15 | var f = F() 16 | f.foo() 17 | } 18 | -------------------------------------------------------------------------------- /test/snapshot/generic-type-member-using-generic-param.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct A { 4 | T*? a 5 | A() { this.a = null } 6 | } 7 | 8 | void main() { var a = A() } 9 | -------------------------------------------------------------------------------- /test/snapshot/generic-type-member-using-generic-param.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | A* a = alloca A 4 | void _0 = call _EN4main1AI3intE4initE(A* a) 5 | return int 0 6 | } 7 | 8 | void _EN4main1AI3intE4initE(A* this) { 9 | int** a = getelementptr this, 0 10 | store int* null to a 11 | return void 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/generic-type-method-call.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct S { 4 | S() { 5 | E().h(); 6 | } 7 | void s() {} 8 | } 9 | 10 | struct A: Copyable { 11 | void h() {} 12 | } 13 | 14 | void main() { 15 | var x = S(); 16 | x.s(); 17 | } 18 | -------------------------------------------------------------------------------- /test/snapshot/generic-type-method-calls-without-this.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct S: Copyable { 4 | void f() { g() } 5 | void g() {} 6 | } 7 | 8 | void main() { 9 | S().f() 10 | S().f() 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/generic-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct A { 4 | T a 5 | } 6 | 7 | void main() { 8 | A a = undefined 9 | A>> aaa = undefined 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/generic-type.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | A* a = alloca A 4 | A>>* aaa = alloca A>> 5 | return int 0 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/generic-type.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %"A" = type { i32 } 3 | %"A>>" = type { %"A>" } 4 | %"A>" = type { %"A" } 5 | %"A" = type { i1 } 6 | 7 | define i32 @main() { 8 | %a = alloca %"A", align 8 9 | %aaa = alloca %"A>>", align 8 10 | ret i32 0 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/global-constant.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | const int qux = 42; 4 | 5 | void main() { 6 | var d = bar; 7 | } 8 | 9 | const bar = 42; 10 | -------------------------------------------------------------------------------- /test/snapshot/global-constant.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | int* d = alloca int 4 | store int 42 to d 5 | return int 0 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/global-constant.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %d = alloca i32, align 4 4 | store i32 42, i32* %d, align 4 5 | ret i32 0 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/global-ptr-to-copyable-as-argument.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | foo(sp) 5 | } 6 | 7 | S*? sp = null 8 | 9 | void foo(S*? p) { } 10 | 11 | struct S: Copyable { 12 | int i 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/global-ptr-to-copyable-as-argument.cx.ir: -------------------------------------------------------------------------------- 1 | global sp = S* null 2 | 3 | int main() { 4 | S* sp.load = load sp 5 | void _0 = call _EN4main3fooEOP1S(S* sp.load) 6 | return int 0 7 | } 8 | 9 | void _EN4main3fooEOP1S(S* p) { 10 | return void 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/global-ptr-to-copyable-as-argument.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %S = type { i32 } 3 | 4 | @sp = private global %S* null 5 | 6 | define i32 @main() { 7 | %sp.load = load %S*, %S** @sp, align 8 8 | call void @_EN4main3fooEOP1S(%S* %sp.load) 9 | ret i32 0 10 | } 11 | 12 | define void @_EN4main3fooEOP1S(%S* %p) { 13 | ret void 14 | } 15 | -------------------------------------------------------------------------------- /test/snapshot/global-variable.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | var foo = 42; 4 | int qux = 42; 5 | 6 | void main() { 7 | foo = 43; 8 | var d = bar; 9 | } 10 | 11 | var bar = 42; 12 | -------------------------------------------------------------------------------- /test/snapshot/global-variable.cx.ir: -------------------------------------------------------------------------------- 1 | global foo = int 42 2 | global qux = int 42 3 | global bar = int 42 4 | 5 | int main() { 6 | int* d = alloca int 7 | store int 43 to foo 8 | int bar.load = load bar 9 | store bar.load to d 10 | return int 0 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/global-variable.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | @foo = private global i32 42 3 | @qux = private global i32 42 4 | @bar = private global i32 42 5 | 6 | define i32 @main() { 7 | %d = alloca i32, align 4 8 | store i32 43, i32* @foo, align 4 9 | %bar.load = load i32, i32* @bar, align 4 10 | store i32 %bar.load, i32* %d, align 4 11 | ret i32 0 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/if-expression.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | extern bool a(); 4 | extern bool b(); 5 | extern bool c(); 6 | extern bool d(); 7 | extern bool e(); 8 | 9 | void main() { 10 | var x = a() ? b() : c() ? d() : e(); 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/if-statement.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | extern void foo(); 4 | extern void bar(); 5 | 6 | void main() { 7 | if false { 8 | foo(); 9 | } else { 10 | bar(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/if-statement.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | extern void foo() 3 | 4 | extern void bar() 5 | 6 | int main() { 7 | br bool false, if.then, if.else 8 | 9 | if.then: 10 | void _0 = call foo() 11 | br if.end 12 | 13 | if.else: 14 | void _1 = call bar() 15 | br if.end 16 | 17 | if.end: 18 | return int 0 19 | } 20 | -------------------------------------------------------------------------------- /test/snapshot/implicit-cast-to-void-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | int* p = undefined; 5 | const int* cp = undefined; 6 | void* v = p; 7 | bar(p); 8 | bar(v); 9 | var b = cast(v); 10 | v = b; 11 | baz(cp); 12 | var i = 0; 13 | baz(&i); 14 | } 15 | 16 | void bar(void* p) {} 17 | 18 | void baz(void*? p) {} 19 | -------------------------------------------------------------------------------- /test/snapshot/implicit-null-comparison-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | bool*? foo = undefined; 5 | bool b = !foo; 6 | if (foo) {} 7 | while (foo) {} 8 | var a = foo ? 1 : 2; 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/import-c-define-integer-hex-constant.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | import "inputs/import-c-defined-integer-hex-constant.h"; 4 | 5 | void main() { 6 | int foo = FOO; 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/import-c-define-integer-hex-constant.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | int* foo = alloca int 4 | store int 35044 to foo 5 | return int 0 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/import-c-define-integer-hex-constant.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %foo = alloca i32, align 4 4 | store i32 35044, i32* %foo, align 4 5 | ret i32 0 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/import-c-enum.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | import "inputs/import-c-enum.h"; 4 | 5 | void main() { 6 | int foo = FooA; 7 | uint bar = BarA; 8 | uint64 qux = QuxA; 9 | int8 qux2 = QuxA; 10 | // FIXME: qux3 and qux4 should be i64 to fit the enum value. 11 | var qux3 = QuxB; 12 | Qux qux4 = qux3; 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/import-c-header.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | import "stdio.h"; 4 | import "foo.h"; 5 | 6 | void main() { 7 | puts("foo bar"); 8 | Foo f = undefined; 9 | f.bar = MAGIC_NUMBER + ANSWER; 10 | f.baz = "foo"; 11 | var bar = getBar(f); 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/import-c-pointer-to-pointer-null-conversion.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | import "inputs/import-c-pointer-to-pointer-null-conversion.h"; 4 | 5 | void main() { 6 | foo(p: null); 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/import-c-pointer-to-pointer-null-conversion.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | void _0 = call foo(char** null) 4 | return int 0 5 | } 6 | 7 | extern void foo(char**) 8 | -------------------------------------------------------------------------------- /test/snapshot/import-c-pointer-to-pointer-null-conversion.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | call void @foo(i8** null) 4 | ret i32 0 5 | } 6 | 7 | declare void @foo(i8**) 8 | -------------------------------------------------------------------------------- /test/snapshot/import-c-typedefed-anonymous-struct.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | import "inputs/import-c-typedefed-anonymous-struct.h"; 4 | 5 | void main() { 6 | Foo x = undefined; 7 | foo(x); 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/import-c-typedefed-anonymous-struct.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | Foo* x = alloca Foo 4 | Foo x.load = load x 5 | void _0 = call foo(Foo x.load) 6 | return int 0 7 | } 8 | 9 | extern void foo(Foo) 10 | -------------------------------------------------------------------------------- /test/snapshot/import-c-typedefed-anonymous-struct.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %Foo = type { i32 } 3 | 4 | define i32 @main() { 5 | %x = alloca %Foo, align 8 6 | %x.load = load %Foo, %Foo* %x, align 4 7 | call void @foo(%Foo %x.load) 8 | ret i32 0 9 | } 10 | 11 | declare void @foo(%Foo) 12 | -------------------------------------------------------------------------------- /test/snapshot/increment-through-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | void f(int* a) { 4 | var p = a; 5 | p++; 6 | a--; 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/increment-through-pointer.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main1fEP3int(int* a) { 3 | int** p = alloca int* 4 | store a to p 5 | int* p.load = load p 6 | int p.load.load = load p.load 7 | int _0 = p.load.load + int 1 8 | store _0 to p.load 9 | int a.load = load a 10 | int _1 = a.load + int -1 11 | store _1 to a 12 | return void 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/infer-generic-args-autoreference.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void f(T* p) {} 4 | 5 | void main() { 6 | var i = 42; 7 | f(i); 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/infer-generic-args-autoreference.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | int* i = alloca int 4 | store int 42 to i 5 | void _0 = call _EN4main1fI3intEEP3int(int* i) 6 | return int 0 7 | } 8 | 9 | void _EN4main1fI3intEEP3int(int* p) { 10 | return void 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/infer-generic-args-autoreference.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %i = alloca i32, align 4 4 | store i32 42, i32* %i, align 4 5 | call void @_EN4main1fI3intEEP3int(i32* %i) 6 | ret i32 0 7 | } 8 | 9 | define void @_EN4main1fI3intEEP3int(i32* %p) { 10 | ret void 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/infer-generic-args-forget-mutable.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void f(Range r) {} 4 | 5 | void main() { 6 | var foo = 0; 7 | var bar = 0; 8 | f(foo..bar); 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/infer-generic-args-reinterpret-int-literal.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | uint u = undefined; 5 | f(0, u); 6 | } 7 | 8 | void f(T a, T b) {} 9 | -------------------------------------------------------------------------------- /test/snapshot/infer-generic-args-reinterpret-int-literal.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | uint* u = alloca uint 4 | uint u.load = load u 5 | void _0 = call _EN4main1fI4uintEE4uint4uint(uint 0, uint u.load) 6 | return int 0 7 | } 8 | 9 | void _EN4main1fI4uintEE4uint4uint(uint a, uint b) { 10 | return void 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/infer-generic-args-reinterpret-int-literal.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %u = alloca i32, align 4 4 | %u.load = load i32, i32* %u, align 4 5 | call void @_EN4main1fI4uintEE4uint4uint(i32 0, i32 %u.load) 6 | ret i32 0 7 | } 8 | 9 | define void @_EN4main1fI4uintEE4uint4uint(i32 %a, i32 %b) { 10 | ret void 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/infer-generic-arguments-from-assignment-lhs.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | List i = List(capacity: 10); 5 | List j = List(); 6 | // List? o = List(); // TODO: Implement generic argument inference from lhs when lhs is Optional. 7 | i = List(); 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/inputs/copyable-type-method-call-before-declaration/a.cx: -------------------------------------------------------------------------------- 1 | void main() { 2 | B().f(); 3 | } 4 | -------------------------------------------------------------------------------- /test/snapshot/inputs/copyable-type-method-call-before-declaration/b.cx: -------------------------------------------------------------------------------- 1 | struct B: Copyable { 2 | void f() {} 3 | } 4 | -------------------------------------------------------------------------------- /test/snapshot/inputs/import-c-defined-integer-hex-constant.h: -------------------------------------------------------------------------------- 1 | #define FOO 0x88E4 2 | -------------------------------------------------------------------------------- /test/snapshot/inputs/import-c-enum.h: -------------------------------------------------------------------------------- 1 | enum { 2 | FooA = -1, 3 | FooB = 0x7FFFFFFF 4 | }; 5 | 6 | enum Bar { 7 | BarA, 8 | BarB = 0x7FFFFFFF 9 | }; 10 | 11 | typedef enum : unsigned long long { 12 | QuxA, 13 | QuxB = 0xFFFFFFFFFFFFFFFF 14 | } Qux; 15 | -------------------------------------------------------------------------------- /test/snapshot/inputs/import-c-pointer-to-pointer-null-conversion.h: -------------------------------------------------------------------------------- 1 | void foo(const char *const *p); 2 | -------------------------------------------------------------------------------- /test/snapshot/inputs/import-c-typedefed-anonymous-struct.h: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | int i; 3 | } Foo; 4 | 5 | void foo(Foo); 6 | -------------------------------------------------------------------------------- /test/snapshot/inputs/imported_generic_type_constructor/a.cx: -------------------------------------------------------------------------------- 1 | struct A { 2 | T*? a 3 | A() { this.a = null } 4 | } 5 | -------------------------------------------------------------------------------- /test/snapshot/int-literal-autocast.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | extern void foo(uint8 a); 4 | 5 | void main() { 6 | foo(1); 7 | uint64 b = 42; 8 | int8 c = -42; 9 | b = b + 1; 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/int-literal-autocast.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | extern void foo(uint8) 3 | 4 | int main() { 5 | uint64* b = alloca uint64 6 | int8* c = alloca int8 7 | void _0 = call foo(uint8 1) 8 | store uint64 42 to b 9 | store int8 -42 to c 10 | uint64 b.load = load b 11 | uint64 _1 = b.load + uint64 1 12 | store _1 to b 13 | return int 0 14 | } 15 | -------------------------------------------------------------------------------- /test/snapshot/int-literal-autocast.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | declare void @foo(i8) 3 | 4 | define i32 @main() { 5 | %b = alloca i64, align 8 6 | %c = alloca i8, align 1 7 | call void @foo(i8 1) 8 | store i64 42, i64* %b, align 4 9 | store i8 -42, i8* %c, align 1 10 | %b.load = load i64, i64* %b, align 4 11 | %1 = add i64 %b.load, 1 12 | store i64 %1, i64* %b, align 4 13 | ret i32 0 14 | } 15 | -------------------------------------------------------------------------------- /test/snapshot/int-literal-plus-float-literal.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var a = 4.0 + 4; 5 | var b = 4 + 4.0; 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/int-literal-plus-float-literal.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | float* a = alloca float 4 | float* b = alloca float 5 | float _0 = float 4 + float 4 6 | store _0 to a 7 | float _1 = float 4 + float 4 8 | store _1 to b 9 | return int 0 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/int-literal-plus-float-literal.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %a = alloca float, align 4 4 | %b = alloca float, align 4 5 | store float 8.000000e+00, float* %a, align 4 6 | store float 8.000000e+00, float* %b, align 4 7 | ret i32 0 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/integer-literal.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var i = 42; 5 | var j = 0 + 0b01; 6 | int k = 0xf * 0o7; 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/integer-literal.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | int* i = alloca int 4 | int* j = alloca int 5 | int* k = alloca int 6 | store int 42 to i 7 | store int 1 to j 8 | store int 105 to k 9 | return int 0 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/integer-literal.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %i = alloca i32, align 4 4 | %j = alloca i32, align 4 5 | %k = alloca i32, align 4 6 | store i32 42, i32* %i, align 4 7 | store i32 1, i32* %j, align 4 8 | store i32 105, i32* %k, align 4 9 | ret i32 0 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/interface-method-definition.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | interface A { 4 | int f(); 5 | int g() { return f() * 2; } 6 | } 7 | 8 | struct B: A { 9 | int f() { return 21; } 10 | } 11 | 12 | void main() { 13 | var b = B(); 14 | var x = b.g(); 15 | } 16 | -------------------------------------------------------------------------------- /test/snapshot/interface.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | interface I { 4 | void f(); 5 | } 6 | -------------------------------------------------------------------------------- /test/snapshot/interface.cx.ir: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emillaine/cx/56117477ad6299391bc13ff5e6cc0ea24c38d9dc/test/snapshot/interface.cx.ir -------------------------------------------------------------------------------- /test/snapshot/interface.cx.ll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emillaine/cx/56117477ad6299391bc13ff5e6cc0ea24c38d9dc/test/snapshot/interface.cx.ll -------------------------------------------------------------------------------- /test/snapshot/local-auto-reference.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct Foo { int i; } 4 | void main() { 5 | Foo f = undefined; 6 | Foo* rf = f; 7 | Foo* pf = f; 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/local-auto-reference.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | Foo* f = alloca Foo 4 | Foo** rf = alloca Foo* 5 | Foo** pf = alloca Foo* 6 | store f to rf 7 | store f to pf 8 | return int 0 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/local-auto-reference.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %Foo = type { i32 } 3 | 4 | define i32 @main() { 5 | %f = alloca %Foo, align 8 6 | %rf = alloca %Foo*, align 8 7 | %pf = alloca %Foo*, align 8 8 | store %Foo* %f, %Foo** %rf, align 8 9 | store %Foo* %f, %Foo** %pf, align 8 10 | ret i32 0 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/loop-variable-name-reuse.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | for (var i in 0...5) { } 5 | for (var i in 0...5) { } 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/member-access-via-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct Foo { 4 | int i; 5 | } 6 | 7 | void get(Foo* f) { 8 | var m = f.i; 9 | } 10 | 11 | void main() { 12 | Foo f = undefined; 13 | Foo* rf = f; 14 | var n = rf.i; 15 | get(rf); 16 | } 17 | -------------------------------------------------------------------------------- /test/snapshot/member-array-subscript.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct C { 4 | int[] a 5 | 6 | void foo() { 7 | _ = a[4] 8 | } 9 | } 10 | 11 | void main() { 12 | C([0,1,2,3,4]).foo(); 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/member-function-call-in-lambda-body.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct X { 4 | int foo() { 5 | return 42; 6 | } 7 | } 8 | 9 | void main() { 10 | var lambda = (X* x) -> x.foo(); 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/member-function-call-in-lambda-body.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | int(X*)** lambda = alloca int(X*)* 4 | store _EN4main9__lambda0EP1X to lambda 5 | return int 0 6 | } 7 | 8 | int _EN4main9__lambda0EP1X(X* x) { 9 | int _0 = call _EN4main1X3fooE(X* x) 10 | return _0 11 | } 12 | 13 | int _EN4main1X3fooE(X* this) { 14 | return int 42 15 | } 16 | -------------------------------------------------------------------------------- /test/snapshot/member-function-call-via-local-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct Foo { 4 | int i; 5 | void bar() { } 6 | } 7 | 8 | void main() { 9 | Foo f = undefined; 10 | Foo* rf = f; 11 | rf.bar(); 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/member-function-call-via-local-pointer.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | Foo* f = alloca Foo 4 | Foo** rf = alloca Foo* 5 | store f to rf 6 | Foo* rf.load = load rf 7 | void _0 = call _EN4main3Foo3barE(Foo* rf.load) 8 | return int 0 9 | } 10 | 11 | void _EN4main3Foo3barE(Foo* this) { 12 | return void 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/member-function-on-different-types.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct Foo { 4 | int i; 5 | void doStuff() { } 6 | } 7 | 8 | struct Bar { 9 | int i; 10 | void doStuff() { } 11 | } 12 | 13 | void main() { 14 | Foo(1).doStuff(); 15 | Bar(2).doStuff(); 16 | } 17 | -------------------------------------------------------------------------------- /test/snapshot/member-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct Foo { 4 | int baz; 5 | 6 | Foo() { this.baz = 42; } 7 | 8 | void bar() { this.baz++; } 9 | 10 | int qux() { return this.baz; } 11 | } 12 | 13 | void main() { 14 | var foo = Foo(); 15 | foo.bar(); 16 | var i = foo.qux(); 17 | } 18 | -------------------------------------------------------------------------------- /test/snapshot/method-call-on-returned-value.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct S: Copyable { 4 | int i; 5 | S() { i = 0; } 6 | void f() {} 7 | } 8 | 9 | struct C { 10 | int i; 11 | C() { i = 0; } 12 | void f() {} 13 | } 14 | 15 | S s() { return S(); } 16 | C c() { return C(); } 17 | 18 | void main() { 19 | s().f(); 20 | c().f(); 21 | S().f(); 22 | C().f(); 23 | } 24 | -------------------------------------------------------------------------------- /test/snapshot/method-return-void.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct C { 4 | void f() { 5 | return 6 | } 7 | } 8 | 9 | void main() { 10 | var c = C() 11 | c.f() 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/method-return-void.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | C* c = alloca C 4 | void _0 = call _EN4main1C4initE(C* c) 5 | void _1 = call _EN4main1C1fE(C* c) 6 | return int 0 7 | } 8 | 9 | void _EN4main1C4initE(C* this) { 10 | return void 11 | } 12 | 13 | void _EN4main1C1fE(C* this) { 14 | return void 15 | } 16 | -------------------------------------------------------------------------------- /test/snapshot/method-return-void.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %C = type {} 3 | 4 | define i32 @main() { 5 | %c = alloca %C, align 8 6 | call void @_EN4main1C4initE(%C* %c) 7 | call void @_EN4main1C1fE(%C* %c) 8 | ret i32 0 9 | } 10 | 11 | define void @_EN4main1C4initE(%C* %this) { 12 | ret void 13 | } 14 | 15 | define void @_EN4main1C1fE(%C* %this) { 16 | ret void 17 | } 18 | -------------------------------------------------------------------------------- /test/snapshot/move-return-value.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct X { 4 | ~X() {} 5 | } 6 | 7 | X f() { 8 | var x = X(); 9 | return x; 10 | } 11 | 12 | void main() { 13 | var a = f(); 14 | } 15 | -------------------------------------------------------------------------------- /test/snapshot/move-type-with-destructor.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | struct Y { 4 | ~Y() {} 5 | } 6 | 7 | void f(Y a, Y* b) { 8 | *b = a; 9 | } 10 | 11 | void g(Y a) { 12 | var b = a; 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/move-type-with-destructor.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main1fE1YP1Y(Y a, Y* b) { 3 | void _0 = call _EN4main1Y6deinitE(Y* b) 4 | store a to b 5 | return void 6 | } 7 | 8 | void _EN4main1Y6deinitE(Y* this) { 9 | return void 10 | } 11 | 12 | void _EN4main1gE1Y(Y a) { 13 | Y* b = alloca Y 14 | store a to b 15 | void _0 = call _EN4main1Y6deinitE(Y* b) 16 | return void 17 | } 18 | -------------------------------------------------------------------------------- /test/snapshot/mutable-local-var-in-generic-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void f() { 4 | var i = 0; 5 | i++; 6 | } 7 | 8 | void main() { 9 | f(); 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/mutable-local-var-in-generic-function.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | void _0 = call _EN4main1fI3intEE() 4 | return int 0 5 | } 6 | 7 | void _EN4main1fI3intEE() { 8 | int* i = alloca int 9 | store int 0 to i 10 | int i.load = load i 11 | int _0 = i.load + int 1 12 | store _0 to i 13 | return void 14 | } 15 | -------------------------------------------------------------------------------- /test/snapshot/mutable-local-var-in-generic-function.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | call void @_EN4main1fI3intEE() 4 | ret i32 0 5 | } 6 | 7 | define void @_EN4main1fI3intEE() { 8 | %i = alloca i32, align 4 9 | store i32 0, i32* %i, align 4 10 | %i.load = load i32, i32* %i, align 4 11 | %1 = add i32 %i.load, 1 12 | store i32 %1, i32* %i, align 4 13 | ret void 14 | } 15 | -------------------------------------------------------------------------------- /test/snapshot/negate-generic-parameter.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | T f(T a) { 4 | return -a 5 | } 6 | 7 | void main() { 8 | f(0.0) 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/negate-generic-parameter.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | float _0 = call _EN4main1fI5floatEE5float(float 0) 4 | return int 0 5 | } 6 | 7 | float _EN4main1fI5floatEE5float(float a) { 8 | float _0 = -a 9 | return _0 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/negate-generic-parameter.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %1 = call float @_EN4main1fI5floatEE5float(float 0.000000e+00) 4 | ret i32 0 5 | } 6 | 7 | define float @_EN4main1fI5floatEE5float(float %a) { 8 | %1 = fneg float %a 9 | ret float %1 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/nested-generic-calls.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | g(42); 5 | g(false); 6 | } 7 | 8 | void g(T t) { 9 | f(t); 10 | } 11 | 12 | void f(T t) {} 13 | -------------------------------------------------------------------------------- /test/snapshot/not.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var b = !!false; 5 | b = !b; 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/not.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | bool* b = alloca bool 4 | bool _0 = !bool false 5 | bool _1 = !_0 6 | store _1 to b 7 | bool b.load = load b 8 | bool _2 = !b.load 9 | store _2 to b 10 | return int 0 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/not.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %b = alloca i1, align 1 4 | store i1 false, i1* %b, align 1 5 | %b.load = load i1, i1* %b, align 1 6 | %1 = xor i1 %b.load, true 7 | store i1 %1, i1* %b, align 1 8 | ret i32 0 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/null-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | int*? foo() { return null; } 4 | 5 | void main() { 6 | var isNull = foo() == null; 7 | var isNonNull = foo() != null; 8 | var ptr = foo(); 9 | bool*? ptr2 = null; 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/null-unsized-array-reference.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | int8[]? a = null 5 | } 6 | -------------------------------------------------------------------------------- /test/snapshot/numeric-conversion.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | uint16 i = 42; 5 | var f = float32(i); 6 | var u = int64(f); 7 | var s = uint(true); 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/optional-pointer-access-without-unwrapping.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -w 2 | 3 | struct Foo { 4 | int i; 5 | void bar() { } 6 | } 7 | 8 | void main() { 9 | Foo*? f = null; 10 | _ = f.i; 11 | var a = f.i; 12 | var b = &f.i; 13 | int* c = f.i; 14 | f.bar(); 15 | *f = *f; 16 | } 17 | -------------------------------------------------------------------------------- /test/snapshot/optional-type-comparison.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | int? a = null; 5 | a == 1; 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/optional-type-non-pointer-return.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | int? f() { 4 | int i = 1; 5 | return i; 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/optional-type-unknown-identifier-bug.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct X { 4 | Y*? y; 5 | 6 | X() { 7 | y = null; 8 | } 9 | 10 | ~X() { 11 | var a = y!.a; 12 | } 13 | } 14 | 15 | struct Y { 16 | T a; 17 | 18 | void f() {} 19 | } 20 | 21 | void main() { 22 | var x = X(); 23 | } 24 | -------------------------------------------------------------------------------- /test/snapshot/overloaded-generic-operator-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | struct S: Copyable {} 4 | 5 | interface I { 6 | void foo(); 7 | } 8 | 9 | void operator==(T* a, T* b) {} 10 | 11 | void operator==(S a, S b) {} 12 | 13 | void f(S s) { 14 | _ = s == s; 15 | } 16 | -------------------------------------------------------------------------------- /test/snapshot/overloaded-generic-operator-function.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4maineqE1S1S(S a, S b) { 3 | return void 4 | } 5 | 6 | void _EN4main1fE1S(S s) { 7 | void _0 = call _EN4maineqE1S1S(S s, S s) 8 | return void 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/overloaded-generic-operator-function.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %S = type {} 3 | 4 | define void @_EN4maineqE1S1S(%S %a, %S %b) { 5 | ret void 6 | } 7 | 8 | define void @_EN4main1fE1S(%S %s) { 9 | call void @_EN4maineqE1S1S(%S %s, %S %s) 10 | ret void 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/overloading-with-param-names.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -w 2 | 3 | struct Foo { 4 | int i 5 | Foo(public int i) { } 6 | Foo(public int qux) { } 7 | void foo(public int i) { } 8 | void foo(public int qux) { } 9 | } 10 | 11 | void foo(public int i) { 12 | Foo(i: i).foo(i: i) 13 | Foo(qux: i).foo(qux: i) 14 | } 15 | 16 | void foo(public int qux) { } 17 | -------------------------------------------------------------------------------- /test/snapshot/packed-struct.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | // RUN: %cx run %s 3 | 4 | import "./packed-struct.h"; 5 | 6 | void main() { 7 | S s = undefined; 8 | s.a = 0xAB; 9 | s.b = 0xCDEF; 10 | s.c = 0; 11 | assert(sizeof(S) == 4); 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/packed-struct.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct S { 4 | uint8_t a; 5 | uint16_t b; 6 | uint8_t c; 7 | } __attribute__((packed)); 8 | -------------------------------------------------------------------------------- /test/snapshot/parameter-auto-reference.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | struct S: Copyable {} 4 | 5 | void f(S s) { 6 | g(s); 7 | } 8 | 9 | void g(S* s) {} 10 | -------------------------------------------------------------------------------- /test/snapshot/parameter-auto-reference.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main1fE1S(S s) { 3 | S* _0 = alloca S 4 | store s to _0 5 | void _1 = call _EN4main1gEP1S(S* _0) 6 | return void 7 | } 8 | 9 | void _EN4main1gEP1S(S* s) { 10 | return void 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/parameter-auto-reference.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %S = type {} 3 | 4 | define void @_EN4main1fE1S(%S %s) { 5 | %1 = alloca %S, align 8 6 | store %S %s, %S* %1, align 1 7 | call void @_EN4main1gEP1S(%S* %1) 8 | ret void 9 | } 10 | 11 | define void @_EN4main1gEP1S(%S* %s) { 12 | ret void 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/parameter-shadows-member-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -w 2 | 3 | struct S { 4 | int i; 5 | S() {} 6 | void bar() {} 7 | void foo(int bar) { 8 | var a = bar; 9 | bar(); 10 | } 11 | } 12 | 13 | void main() { 14 | var s = S(); 15 | s.foo(30); 16 | } 17 | -------------------------------------------------------------------------------- /test/snapshot/parameter-shadows-member-variable.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -w 2 | 3 | struct S { 4 | int bar; 5 | S() {} 6 | void foo(int bar) { 7 | _ = bar + 42; 8 | } 9 | } 10 | 11 | void main() { 12 | S().foo(30); 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/parameter-shadows-member-variable.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | S* _0 = alloca S 4 | void _1 = call _EN4main1S4initE(S* _0) 5 | void _2 = call _EN4main1S3fooE3int(S* _0, int 30) 6 | return int 0 7 | } 8 | 9 | void _EN4main1S3fooE3int(S* this, int bar) { 10 | int _0 = bar + int 42 11 | return void 12 | } 13 | 14 | void _EN4main1S4initE(S* this) { 15 | return void 16 | } 17 | -------------------------------------------------------------------------------- /test/snapshot/pass-constant-by-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | const int i = 0; 4 | 5 | struct S { 6 | void f(T* t) {} 7 | } 8 | 9 | void main() { 10 | var s = S(); 11 | s.f(/*&*/i); // TODO: Allow '&' here or don't allow mutable pointers to constants at all. 12 | s.f(i); 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/pass-non-null-pointer-as-nullable.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void foo(int*? p) {} 4 | 5 | void main() { 6 | var i = 42; 7 | var x = &i; 8 | foo(x); 9 | foo(i); 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/pass-temporary-object-by-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -w 2 | 3 | struct A: Copyable { 4 | int i; 5 | A() {} 6 | } 7 | 8 | struct B { 9 | int i; 10 | B() {} 11 | } 12 | 13 | void f(A* a) {} 14 | void f(B* b) {} 15 | void f(int* i) {} 16 | 17 | void main() { 18 | A a = undefined; 19 | B b = undefined; 20 | f(A()); 21 | f(B()); 22 | f(0); 23 | } 24 | -------------------------------------------------------------------------------- /test/snapshot/pointer-comparison-operator.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | void foo(const int*? a, int* b) { 4 | a == b; 5 | a != b; 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/pointer-comparison-operator.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main3fooEOP3intP3int(int* a, int* b) { 3 | bool _0 = a == b 4 | bool _1 = a != b 5 | return void 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/pointer-comparison-operator.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define void @_EN4main3fooEOP3intP3int(i32* %a, i32* %b) { 3 | %1 = icmp eq i32* %a, %b 4 | %2 = icmp ne i32* %a, %b 5 | ret void 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/pointer-comparison.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | bool _EN4mainltEP1XP1X(X* a, X* b) { 3 | return bool true 4 | } 5 | 6 | void _EN4main2fxEP1XP1XP4voidP4void(X* a, X* b, void* v1, void* v2) { 7 | bool _0 = a == b 8 | bool _1 = a < b 9 | bool _2 = call _EN4mainltEP1XP1X(X* a, X* b) 10 | bool _3 = v1 != v2 11 | bool _4 = v1 >= v2 12 | return void 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/pointer-constructor.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | void foo(char** p, char* x) { 4 | char** pp = undefined; 5 | (&pp).init(p); 6 | pp.init(x); 7 | (*pp).init('x'); 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/pointer-constructor.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main3fooEPP4charP4char(char** p, char* x) { 3 | char*** pp = alloca char** 4 | store p to pp 5 | char** pp.load = load pp 6 | store x to pp.load 7 | char** pp.load_0 = load pp 8 | char* pp.load.load = load pp.load_0 9 | store char 120 to pp.load.load 10 | return void 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/pointer-to-array-of-pointers.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | extern char*[*]? b(); 4 | 5 | void main() { 6 | var s = b(); 7 | var i = 0; 8 | printf("%s\n", s![i]); 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/pointer-to-array-with-unknown-size.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var a = [1, 2, 3]; 5 | int[*] p = &a[0]; 6 | p = a; 7 | p = &a; 8 | var t = p[1]; 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/range-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | int foo(Range r) { 4 | var sum = 0; 5 | for (var i in r) { 6 | sum += i; 7 | } 8 | return sum; 9 | } 10 | 11 | int main() { 12 | return foo(0..5); 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/reassign-type-with-destructor.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct X { 4 | ~X() {} 5 | } 6 | 7 | void main() { 8 | var x = X(); 9 | x = X(); 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/recursive-generic-enum.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct S { 4 | T*? e; 5 | } 6 | 7 | enum E { 8 | A(S s), 9 | B(int[12] b), 10 | } 11 | 12 | void main() { 13 | E e = E.A(S(E.A(S(null)))); 14 | } 15 | -------------------------------------------------------------------------------- /test/snapshot/recursive-type.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | struct S: Copyable { 4 | S* next 5 | } 6 | 7 | void f(S s) {} 8 | -------------------------------------------------------------------------------- /test/snapshot/recursive-type.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main1fE1S(S s) { 3 | return void 4 | } 5 | -------------------------------------------------------------------------------- /test/snapshot/recursive-type.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %S = type { %S* } 3 | 4 | define void @_EN4main1fE1S(%S %s) { 5 | ret void 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/return-statement.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | int main() { 4 | return foo(); 5 | } 6 | 7 | int foo() { 8 | foo(); 9 | return 42; 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/return-statement.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | int _0 = call _EN4main3fooE() 4 | return _0 5 | } 6 | 7 | int _EN4main3fooE() { 8 | int _0 = call _EN4main3fooE() 9 | return int 42 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/return-statement.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %1 = call i32 @_EN4main3fooE() 4 | ret i32 %1 5 | } 6 | 7 | define i32 @_EN4main3fooE() { 8 | %1 = call i32 @_EN4main3fooE() 9 | ret i32 42 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/reuse-variable-name-in-unrelated-scope.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | void f() { 4 | var index = 0; 5 | var x = g(); 6 | X().g(); 7 | } 8 | 9 | X g() { 10 | var x = X(); 11 | return x; 12 | } 13 | 14 | struct X { 15 | void g() { 16 | var index = 0; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/snapshot/signed-vs-unsigned-arithmetic.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | void foo(int i, uint u) { 4 | var a = i < i; 5 | a = u < u; 6 | a = i > i; 7 | a = u > u; 8 | a = i <= i; 9 | a = u <= u; 10 | a = i >= i; 11 | a = u >= u; 12 | var b = i / i; 13 | var c = u / u; 14 | } 15 | -------------------------------------------------------------------------------- /test/snapshot/stack-allocated-array-of-pointers.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | void*[3] a = undefined; 5 | int*[2] b = undefined; 6 | float32**[1] c = undefined; 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/stack-allocated-array-of-pointers.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | void*[3]* a = alloca void*[3] 4 | int*[2]* b = alloca int*[2] 5 | float32**[1]* c = alloca float32**[1] 6 | return int 0 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/stack-allocated-array-of-pointers.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | %a = alloca [3 x i8*], align 8 4 | %b = alloca [2 x i32*], align 8 5 | %c = alloca [1 x float**], align 8 6 | ret i32 0 7 | } 8 | -------------------------------------------------------------------------------- /test/snapshot/string-literal.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var s = "foo"; 5 | } 6 | -------------------------------------------------------------------------------- /test/snapshot/string-literal.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | string* s = alloca string 4 | string* __str = alloca string 5 | void _0 = call _EN3std6string4initEP4char3int(string* __str, char* "foo", int 3) 6 | string __str.load = load __str 7 | store __str.load to s 8 | return int 0 9 | } 10 | 11 | void _EN3std6string4initEP4char3int(string* this, char* pointer, int length) { 12 | } 13 | -------------------------------------------------------------------------------- /test/snapshot/string-plus-assign.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var a = StringBuffer() 5 | a += "" 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/struct-with-destructor-as-value-param.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | void foo(A a) {} 4 | 5 | struct A { 6 | T i; 7 | ~A() {} 8 | } 9 | -------------------------------------------------------------------------------- /test/snapshot/struct-with-destructor-as-value-param.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | void _EN4main3fooE1AI3intE(A a) { 3 | A* _0 = alloca A 4 | store a to _0 5 | void _1 = call _EN4main1AI3intE6deinitE(A* _0) 6 | return void 7 | } 8 | 9 | void _EN4main1AI3intE6deinitE(A* this) { 10 | return void 11 | } 12 | -------------------------------------------------------------------------------- /test/snapshot/struct-with-destructor-as-value-param.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | %"A" = type { i32 } 3 | 4 | define void @_EN4main3fooE1AI3intE(%"A" %a) { 5 | %1 = alloca %"A", align 8 6 | store %"A" %a, %"A"* %1, align 4 7 | call void @_EN4main1AI3intE6deinitE(%"A"* %1) 8 | ret void 9 | } 10 | 11 | define void @_EN4main1AI3intE6deinitE(%"A"* %this) { 12 | ret void 13 | } 14 | -------------------------------------------------------------------------------- /test/snapshot/temporary-unsized-array-argument.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void f(T[] a) { 4 | var s = a.size(); 5 | } 6 | 7 | void main() { 8 | f([1,2,3]); 9 | f([1,2,3]); 10 | } 11 | -------------------------------------------------------------------------------- /test/snapshot/tuple-return-by-pointer.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | struct S { 4 | (int a) t; 5 | 6 | (int a)* f() { 7 | return &t; 8 | } 9 | 10 | (int a)* g() { 11 | return t; 12 | } 13 | } 14 | 15 | void main() { 16 | var s = S((a: 1)); 17 | var f = s.f(); 18 | var g = s.g(); 19 | } 20 | -------------------------------------------------------------------------------- /test/snapshot/tuple.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | (bool c, (float e) d) f() { 4 | var d = (e: -1.0); 5 | var a = (a: 42, b: (c: false, d)); 6 | var b = a.b; 7 | var e = b.d.e; 8 | var p = &a.b; 9 | b = *p; 10 | e = p.d.e; 11 | e = (x: 1.0, y: 2.0).x; 12 | return b; 13 | } 14 | 15 | (bool, float) g() { 16 | return (true, 1); 17 | } 18 | -------------------------------------------------------------------------------- /test/snapshot/uninitialized-global.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | int i = undefined; 4 | -------------------------------------------------------------------------------- /test/snapshot/uninitialized-global.cx.ir: -------------------------------------------------------------------------------- 1 | global i = int undefined 2 | -------------------------------------------------------------------------------- /test/snapshot/uninitialized-global.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | @i = private global i32 undef 3 | -------------------------------------------------------------------------------- /test/snapshot/unwrap.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | extern void*? f(); 4 | 5 | void main() { 6 | uint8* byte = cast(f())!; 7 | uint8[1]*? ptr = cast(f()); 8 | ptr![0] = 1; 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/variadic-c-function.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | var f = 4.2; 5 | printf("%d %f", -3, f); 6 | } 7 | -------------------------------------------------------------------------------- /test/snapshot/variadic-c-function.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | float* f = alloca float 4 | store float 4.19999981 to f 5 | float f.load = load f 6 | int _0 = call printf(char* "%d %f", int -3, float f.load) 7 | return int 0 8 | } 9 | 10 | extern int printf(char*) 11 | -------------------------------------------------------------------------------- /test/snapshot/variadic-function-decl.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots -Wno-unused 2 | 3 | extern void f(int i, ...); 4 | -------------------------------------------------------------------------------- /test/snapshot/variadic-function-decl.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | extern void f(int) 3 | -------------------------------------------------------------------------------- /test/snapshot/variadic-function-decl.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | declare void @f(i32, ...) 3 | -------------------------------------------------------------------------------- /test/snapshot/void-main-return.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | void main() { 4 | return; 5 | } 6 | -------------------------------------------------------------------------------- /test/snapshot/void-main-return.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | int main() { 3 | return int 0 4 | } 5 | -------------------------------------------------------------------------------- /test/snapshot/void-main-return.cx.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @main() { 3 | ret i32 0 4 | } 5 | -------------------------------------------------------------------------------- /test/snapshot/while-loop.cx: -------------------------------------------------------------------------------- 1 | // RUN: check-snapshots 2 | 3 | extern bool foo(); 4 | 5 | void main() { 6 | while foo() { 7 | foo(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/snapshot/while-loop.cx.ir: -------------------------------------------------------------------------------- 1 | 2 | extern bool foo() 3 | 4 | int main() { 5 | br loop.condition 6 | 7 | loop.condition: 8 | bool _0 = call foo() 9 | br _0, loop.body, loop.end 10 | 11 | loop.body: 12 | bool _1 = call foo() 13 | br loop.condition 14 | 15 | loop.end: 16 | return int 0 17 | } 18 | -------------------------------------------------------------------------------- /test/stdlib/empty-list-removeFirst.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx run %s 2>&1 | %FileCheck %s 2 | 3 | void main() { 4 | var array = List(); 5 | array.removeFirst(); 6 | } 7 | 8 | // CHECK: Called removeFirst() on empty List 9 | -------------------------------------------------------------------------------- /test/stdlib/empty-list-removeLast.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx run %s 2>&1 | %FileCheck %s 2 | 3 | void main() { 4 | var array = List(); 5 | array.removeLast(); 6 | } 7 | 8 | // CHECK: Called removeLast() on empty List 9 | -------------------------------------------------------------------------------- /test/stdlib/list-out-of-bounds-access.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx run %s 2>&1 | %FileCheck %s 2 | 3 | int main() { 4 | return List()[0]; 5 | } 6 | 7 | // CHECK: List index 0 is out of bounds, size is 0 8 | -------------------------------------------------------------------------------- /test/stdlib/range-tests.cx: -------------------------------------------------------------------------------- 1 | // RUN: check_exit_status 0 %cx run -Werror %s 2 | 3 | void main() { 4 | var a = 1..5; 5 | var b = 1...5; 6 | 7 | assert(a.size() == 4); 8 | assert(b.size() == 5); 9 | 10 | assert(a.end() == 5); 11 | assert(b.end() == 5); 12 | } 13 | -------------------------------------------------------------------------------- /test/stdlib/string-substr-out-of-bounds.cx: -------------------------------------------------------------------------------- 1 | // RUN: %not %cx run %s 2>&1 | %FileCheck %s 2 | 3 | void main() { 4 | var s = StringBuffer("ok"); 5 | s.substr(0..5); 6 | } 7 | 8 | // CHECK: StringBuffer.substr: index 5 is out of bounds, size is 2 9 | -------------------------------------------------------------------------------- /test/true: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | 5 | sys.exit(0) 6 | --------------------------------------------------------------------------------