Skip to content

Commit 749a419

Browse files
committed
Refactor ABI options as part of HIR function qualifiers
The AST has an ABI string as part of the function qualifiers, this was the same in the HIR as it was initially a copy-paste. This patch changes the HIR function qualifiers to have an enum of ABI options, during HIR lowering the enum is setup and if an unknown ABI option is specified an error is emitted.
1 parent 865b609 commit 749a419

File tree

8 files changed

+54
-61
lines changed

8 files changed

+54
-61
lines changed

gcc/rust/ast/rust-item.h

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -484,25 +484,20 @@ struct SelfParam
484484
// Qualifiers for function, i.e. const, unsafe, extern etc.
485485
struct FunctionQualifiers
486486
{
487-
public:
488-
/* Whether the function is neither const nor async, const only, or async
489-
* only. */
490-
491487
private:
492488
AsyncConstStatus const_status;
493489
bool has_unsafe;
494490
bool has_extern;
495-
std::string extern_abi; // e.g. extern "C" fn() -> i32 {}
496-
// TODO: maybe ensure that extern_abi only exists if extern exists?
497-
498-
// should this store location info?
491+
std::string extern_abi;
492+
Location locus;
499493

500494
public:
501-
FunctionQualifiers (AsyncConstStatus const_status, bool has_unsafe,
502-
bool has_extern = false,
495+
FunctionQualifiers (Location locus, AsyncConstStatus const_status,
496+
bool has_unsafe, bool has_extern = false,
503497
std::string extern_abi = std::string ())
504498
: const_status (const_status), has_unsafe (has_unsafe),
505-
has_extern (has_extern), extern_abi (std::move (extern_abi))
499+
has_extern (has_extern), extern_abi (std::move (extern_abi)),
500+
locus (locus)
506501
{
507502
if (!this->extern_abi.empty ())
508503
{
@@ -517,6 +512,9 @@ struct FunctionQualifiers
517512
bool is_unsafe () const { return has_unsafe; }
518513
bool is_extern () const { return has_extern; }
519514
std::string get_extern_abi () const { return extern_abi; }
515+
bool has_abi () const { return !extern_abi.empty (); }
516+
517+
Location get_locus () const { return locus; }
520518
};
521519

522520
// A function parameter
@@ -723,7 +721,7 @@ class Method : public InherentImplItem, public TraitImplItem
723721
// Creates an error state method.
724722
static Method create_error ()
725723
{
726-
return Method ("", FunctionQualifiers (NONE, true),
724+
return Method ("", FunctionQualifiers (Location (), NONE, true),
727725
std::vector<std::unique_ptr<GenericParam>> (),
728726
SelfParam::create_error (), std::vector<FunctionParam> (),
729727
nullptr, WhereClause::create_empty (), nullptr,

gcc/rust/hir/rust-ast-lower-item.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -800,15 +800,23 @@ class ASTLoweringItem : public ASTLoweringBase
800800
extern_items.push_back (std::unique_ptr<HIR::ExternalItem> (lowered));
801801
}
802802

803+
ABI abi = ABI::RUST;
804+
if (extern_block.has_abi ())
805+
{
806+
const std::string &extern_abi = extern_block.get_abi ();
807+
abi = get_abi_from_string (extern_abi);
808+
if (abi == ABI::UNKNOWN)
809+
rust_error_at (extern_block.get_locus (), "unknown ABI option");
810+
}
811+
803812
auto crate_num = mappings->get_current_crate ();
804813
Analysis::NodeMapping mapping (crate_num, extern_block.get_node_id (),
805814
mappings->get_next_hir_id (crate_num),
806815
mappings->get_next_localdef_id (crate_num));
807816

808817
HIR::ExternBlock *hir_extern_block
809-
= new HIR::ExternBlock (mapping, extern_block.get_abi (),
810-
std::move (extern_items), std::move (vis),
811-
extern_block.get_inner_attrs (),
818+
= new HIR::ExternBlock (mapping, abi, std::move (extern_items),
819+
std::move (vis), extern_block.get_inner_attrs (),
812820
extern_block.get_outer_attrs (),
813821
extern_block.get_locus ());
814822

gcc/rust/hir/rust-ast-lower.cc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -602,11 +602,17 @@ ASTLoweringBase::lower_qualifiers (const AST::FunctionQualifiers &qualifiers)
602602
= qualifiers.is_unsafe () ? Unsafety::Unsafe : Unsafety::Normal;
603603
bool has_extern = qualifiers.is_extern ();
604604

605-
// FIXME turn this into the Rust::ABI enum
606-
std::string extern_abi = qualifiers.get_extern_abi ();
605+
ABI abi = ABI::RUST;
606+
if (qualifiers.has_abi ())
607+
{
608+
const std::string &extern_abi = qualifiers.get_extern_abi ();
609+
abi = get_abi_from_string (extern_abi);
610+
if (has_extern && abi == ABI::UNKNOWN)
611+
rust_error_at (qualifiers.get_locus (), "unknown ABI option");
612+
}
607613

608614
return HIR::FunctionQualifiers (qualifiers.get_const_status (), unsafety,
609-
has_extern, extern_abi);
615+
has_extern, abi);
610616
}
611617

612618
void

gcc/rust/hir/tree/rust-hir-full-test.cc

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,10 +1030,7 @@ ExternBlock::as_string () const
10301030
std::string str = VisItem::as_string ();
10311031

10321032
str += "extern ";
1033-
if (has_abi ())
1034-
{
1035-
str += "\"" + abi + "\" ";
1036-
}
1033+
str += "\"" + get_string_from_abi (abi) + "\" ";
10371034

10381035
// inner attributes
10391036
str += "\n inner attributes: ";
@@ -2058,10 +2055,7 @@ FunctionQualifiers::as_string () const
20582055
if (has_extern)
20592056
{
20602057
str += "extern";
2061-
if (extern_abi != "")
2062-
{
2063-
str += " \"" + extern_abi + "\"";
2064-
}
2058+
str += " \"" + get_string_from_abi (abi) + "\"";
20652059
}
20662060

20672061
return str;

gcc/rust/hir/tree/rust-hir-item.h

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#ifndef RUST_HIR_ITEM_H
2020
#define RUST_HIR_ITEM_H
2121

22+
#include "rust-abi.h"
2223
#include "rust-ast-full-decls.h"
2324
#include "rust-common.h"
2425
#include "rust-hir.h"
@@ -481,28 +482,22 @@ struct FunctionQualifiers
481482
AsyncConstStatus const_status;
482483
Unsafety unsafety;
483484
bool has_extern;
484-
std::string extern_abi; // e.g. extern "C" fn() -> i32 {}
485-
// TODO: maybe ensure that extern_abi only exists if extern exists?
485+
ABI abi;
486486

487487
public:
488488
FunctionQualifiers (AsyncConstStatus const_status, Unsafety unsafety,
489-
bool has_extern = false,
490-
std::string extern_abi = std::string ())
489+
bool has_extern, ABI abi)
491490
: const_status (const_status), unsafety (unsafety), has_extern (has_extern),
492-
extern_abi (std::move (extern_abi))
493-
{
494-
if (!this->extern_abi.empty ())
495-
{
496-
// having extern is required; not having it is an implementation error
497-
gcc_assert (has_extern);
498-
}
499-
}
491+
abi (abi)
492+
{}
500493

501494
std::string as_string () const;
502495

503496
AsyncConstStatus get_status () const { return const_status; }
504497

505498
bool is_const () const { return const_status == AsyncConstStatus::CONST_FN; }
499+
500+
ABI get_abi () const { return abi; }
506501
};
507502

508503
// A function parameter
@@ -3082,15 +3077,9 @@ class ExternalFunctionItem : public ExternalItem
30823077
// An extern block HIR node
30833078
class ExternBlock : public VisItem
30843079
{
3085-
// bool has_abi;
3086-
std::string abi;
3087-
3088-
// bool has_inner_attrs;
3080+
ABI abi;
30893081
AST::AttrVec inner_attrs;
3090-
3091-
// bool has_extern_items;
30923082
std::vector<std::unique_ptr<ExternalItem>> extern_items;
3093-
30943083
Location locus;
30953084

30963085
public:
@@ -3102,17 +3091,14 @@ class ExternBlock : public VisItem
31023091
// Returns whether extern block has extern items.
31033092
bool has_extern_items () const { return !extern_items.empty (); }
31043093

3105-
// Returns whether extern block has ABI name.
3106-
bool has_abi () const { return !abi.empty (); }
3107-
3108-
std::string get_abi () const { return abi; }
3094+
ABI get_abi () const { return abi; }
31093095

3110-
ExternBlock (Analysis::NodeMapping mappings, std::string abi,
3096+
ExternBlock (Analysis::NodeMapping mappings, ABI abi,
31113097
std::vector<std::unique_ptr<ExternalItem>> extern_items,
31123098
Visibility vis, AST::AttrVec inner_attrs,
31133099
AST::AttrVec outer_attrs, Location locus)
31143100
: VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
3115-
abi (std::move (abi)), inner_attrs (std::move (inner_attrs)),
3101+
abi (abi), inner_attrs (std::move (inner_attrs)),
31163102
extern_items (std::move (extern_items)), locus (locus)
31173103
{}
31183104

gcc/rust/parse/rust-parse-impl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2620,13 +2620,13 @@ AST::FunctionQualifiers
26202620
Parser<ManagedTokenSource>::parse_function_qualifiers ()
26212621
{
26222622
AsyncConstStatus const_status = NONE;
2623-
// bool has_const = false;
26242623
bool has_unsafe = false;
26252624
bool has_extern = false;
26262625
std::string abi;
26272626

26282627
// Check in order of const, unsafe, then extern
26292628
const_TokenPtr t = lexer.peek_token ();
2629+
Location locus = t->get_locus ();
26302630
switch (t->get_id ())
26312631
{
26322632
case CONST:
@@ -2662,7 +2662,7 @@ Parser<ManagedTokenSource>::parse_function_qualifiers ()
26622662
}
26632663
}
26642664

2665-
return AST::FunctionQualifiers (const_status, has_unsafe, has_extern,
2665+
return AST::FunctionQualifiers (locus, const_status, has_unsafe, has_extern,
26662666
std::move (abi));
26672667
}
26682668

gcc/rust/typecheck/rust-hir-type-check-implitem.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,17 +127,11 @@ class TypeCheckTopLevelExternItem : public TypeCheckBase
127127
function.get_item_name ()),
128128
function.get_locus ()};
129129

130-
auto abi = get_abi_from_string (parent.get_abi ());
131-
if (abi == ABI::UNKNOWN)
132-
{
133-
rust_error_at (parent.get_locus (), "unknown abi");
134-
}
135-
136130
auto fnType = new TyTy::FnType (function.get_mappings ().get_hirid (),
137131
function.get_mappings ().get_defid (),
138132
function.get_item_name (), ident, flags,
139-
abi, std::move (params), ret_type,
140-
std::move (substitutions));
133+
parent.get_abi (), std::move (params),
134+
ret_type, std::move (substitutions));
141135

142136
context->insert_type (function.get_mappings (), fnType);
143137
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
extern "foobar" {
2+
// { dg-error "unknown ABI option" "" { target *-*-* } .-1 }
3+
fn printf(s: *const i8, ...);
4+
}
5+
6+
pub extern "baz" fn test() {}
7+
// { dg-error "unknown ABI option" "" { target *-*-* } .-1 }

0 commit comments

Comments
 (0)