Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement host_flag? macro method, not affected by cross-compilation #9049

Merged
merged 4 commits into from
May 11, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/compiler/crystal/macros.cr
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ module Crystal::Macros
def flag?(name) : BoolLiteral
end

# Returns whether a [compile-time flag](https://crystal-lang.org/docs/syntax_and_semantics/compile_time_flags.html)
# is set for the *host* platform, which can differ from the target platform
# (`flag?`) during cross-compilation.
#
# ```
# {{ host_flag?(:win32) }} # true or false
# ```
def host_flag?(name) : BoolLiteral
end

# Prints AST nodes at compile-time. Useful for debugging macros.
def puts(*expressions) : Nop
end
Expand Down
16 changes: 12 additions & 4 deletions src/compiler/crystal/macros/methods.cr
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ module Crystal
interpret_debug(node)
when "env"
interpret_env(node)
when "flag?"
when "flag?", "host_flag?"
interpret_flag?(node)
when "puts"
interpret_puts(node)
Expand Down Expand Up @@ -145,10 +145,18 @@ module Crystal
def interpret_flag?(node)
if node.args.size == 1
node.args[0].accept self
flag = @last.to_macro_id
@last = BoolLiteral.new(@program.has_flag?(flag))
flag_name = @last.to_macro_id
flags = case node.name
straight-shoota marked this conversation as resolved.
Show resolved Hide resolved
when "flag?"
@program.flags
when "host_flag?"
@program.host_flags
else
raise "Bug: unexpected macro method #{node.name}"
end
@last = BoolLiteral.new(flags.includes?(flag_name))
else
node.wrong_number_of_arguments "macro call 'flag?'", node.args.size, 1
node.wrong_number_of_arguments "macro call '#{node.name}'", node.args.size, 1
end
end

Expand Down
29 changes: 17 additions & 12 deletions src/compiler/crystal/semantic/flags.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class Crystal::Program
@flags : Set(String)?
@host_flags : Set(String)?

# Returns the flags for this program. By default these
# are computed from the target triple (for example x86_64,
Expand All @@ -11,6 +12,10 @@ class Crystal::Program
@flags ||= flags_for_target(codegen_target)
end

def host_flags
@host_flags ||= flags_for_target(Config.default_target)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also suggest to rename Config.default_target to Config.host_target because that's what it is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, didn't turn out too big.

end

# Returns `true` if *name* is in the program's flags.
def has_flag?(name : String)
flags.includes?(name)
Expand All @@ -20,26 +25,26 @@ class Crystal::Program
codegen_target.pointer_bit_width == 64
end

private def flags_for_target(codegen_target)
private def flags_for_target(target)
flags = Set(String).new

flags.add codegen_target.architecture
flags.add codegen_target.vendor
flags.concat codegen_target.environment_parts
flags.add target.architecture
flags.add target.vendor
flags.concat target.environment_parts

flags.add "bits#{codegen_target.pointer_bit_width}"
flags.add "bits#{target.pointer_bit_width}"

flags.add "armhf" if codegen_target.armhf?
flags.add "armhf" if target.armhf?

flags.add "unix" if codegen_target.unix?
flags.add "win32" if codegen_target.win32?
flags.add "unix" if target.unix?
flags.add "win32" if target.win32?

flags.add "darwin" if codegen_target.macos?
if codegen_target.freebsd?
flags.add "darwin" if target.macos?
if target.freebsd?
flags.add "freebsd"
flags.add "freebsd#{codegen_target.freebsd_version}"
flags.add "freebsd#{target.freebsd_version}"
end
flags.add "openbsd" if codegen_target.openbsd?
flags.add "openbsd" if target.openbsd?

flags
end
Expand Down