Skip to content

Commit 77a4950

Browse files
bors[bot]philberty
andauthored
Merge #999
999: Refactor ABI options as part of HIR function qualifiers r=philberty a=philberty This is a refactor to cleanup HIR::ExternBlock and HIR::FunctionQualifiers to have an enum of ABI options to improve the error handling. Co-authored-by: Philip Herron <[email protected]>
2 parents 39c0425 + 749a419 commit 77a4950

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)