Base tests and examples
This commit is contained in:
@@ -25,7 +25,7 @@ jobs:
|
||||
git submodule init
|
||||
git submodule update
|
||||
cd tree-sitter-cpp && git checkout origin/master && cd ..
|
||||
cp tree-sitter-cpp/corpus/* test/corpus
|
||||
cp tree-sitter-cpp/test/corpus/* test/corpus
|
||||
npm test
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
|
||||
Vendored
+147
@@ -0,0 +1,147 @@
|
||||
#ifndef MARKER_INDEX_H_
|
||||
#define MARKER_INDEX_H_
|
||||
|
||||
#include "flat_set.h"
|
||||
#include "point.h"
|
||||
#include "range.h"
|
||||
#include <random>
|
||||
#include <unordered_map>
|
||||
|
||||
class MarkerIndex {
|
||||
public:
|
||||
using MarkerId = unsigned;
|
||||
using MarkerIdSet = flat_set<MarkerId>;
|
||||
|
||||
struct SpliceResult {
|
||||
flat_set<MarkerId> touch;
|
||||
flat_set<MarkerId> inside;
|
||||
flat_set<MarkerId> overlap;
|
||||
flat_set<MarkerId> surround;
|
||||
};
|
||||
|
||||
struct Boundary {
|
||||
Point position;
|
||||
flat_set<MarkerId> starting;
|
||||
flat_set<MarkerId> ending;
|
||||
};
|
||||
|
||||
struct BoundaryQueryResult {
|
||||
std::vector<MarkerId> containing_start;
|
||||
std::vector<Boundary> boundaries;
|
||||
};
|
||||
|
||||
MarkerIndex(unsigned seed = 0u);
|
||||
~MarkerIndex();
|
||||
int generate_random_number();
|
||||
void insert(MarkerId id, Point start, Point end);
|
||||
void set_exclusive(MarkerId id, bool exclusive);
|
||||
void remove(MarkerId id);
|
||||
bool has(MarkerId id);
|
||||
SpliceResult splice(Point start, Point old_extent, Point new_extent);
|
||||
Point get_start(MarkerId id) const;
|
||||
Point get_end(MarkerId id) const;
|
||||
Range get_range(MarkerId id) const;
|
||||
|
||||
int compare(MarkerId id1, MarkerId id2) const;
|
||||
flat_set<MarkerId> find_intersecting(Point start, Point end);
|
||||
flat_set<MarkerId> find_containing(Point start, Point end);
|
||||
flat_set<MarkerId> find_contained_in(Point start, Point end);
|
||||
flat_set<MarkerId> find_starting_in(Point start, Point end);
|
||||
flat_set<MarkerId> find_starting_at(Point position);
|
||||
flat_set<MarkerId> find_ending_in(Point start, Point end);
|
||||
flat_set<MarkerId> find_ending_at(Point position);
|
||||
BoundaryQueryResult find_boundaries_after(Point start, size_t max_count);
|
||||
|
||||
std::unordered_map<MarkerId, Range> dump();
|
||||
|
||||
private:
|
||||
friend class Iterator;
|
||||
|
||||
struct Node {
|
||||
Node *parent;
|
||||
Node *left;
|
||||
Node *right;
|
||||
Point left_extent;
|
||||
flat_set<MarkerId> left_marker_ids;
|
||||
flat_set<MarkerId> right_marker_ids;
|
||||
flat_set<MarkerId> start_marker_ids;
|
||||
flat_set<MarkerId> end_marker_ids;
|
||||
int priority;
|
||||
|
||||
Node(Node *parent, Point left_extent);
|
||||
bool is_marker_endpoint();
|
||||
};
|
||||
|
||||
class Iterator {
|
||||
public:
|
||||
Iterator(MarkerIndex *marker_index);
|
||||
void reset();
|
||||
Node *insert_marker_start(const MarkerId &id, const Point &start_position,
|
||||
const Point &end_position);
|
||||
Node *insert_marker_end(const MarkerId &id, const Point &start_position,
|
||||
const Point &end_position);
|
||||
Node *insert_splice_boundary(const Point &position, bool is_insertion_end);
|
||||
void find_intersecting(const Point &start, const Point &end,
|
||||
flat_set<MarkerId> *result);
|
||||
void find_contained_in(const Point &start, const Point &end,
|
||||
flat_set<MarkerId> *result);
|
||||
void find_starting_in(const Point &start, const Point &end,
|
||||
flat_set<MarkerId> *result);
|
||||
void find_ending_in(const Point &start, const Point &end,
|
||||
flat_set<MarkerId> *result);
|
||||
void find_boundaries_after(Point start, size_t max_count,
|
||||
BoundaryQueryResult *result);
|
||||
std::unordered_map<MarkerId, Range> dump();
|
||||
|
||||
private:
|
||||
void ascend();
|
||||
void descend_left();
|
||||
void descend_right();
|
||||
void move_to_successor();
|
||||
void seek_to_first_node_greater_than_or_equal_to(const Point &position);
|
||||
void mark_right(const MarkerId &id, const Point &start_position,
|
||||
const Point &end_position);
|
||||
void mark_left(const MarkerId &id, const Point &start_position,
|
||||
const Point &end_position);
|
||||
Node *insert_left_child(const Point &position);
|
||||
Node *insert_right_child(const Point &position);
|
||||
void check_intersection(const Point &start, const Point &end,
|
||||
flat_set<MarkerId> *results);
|
||||
void cache_node_position() const;
|
||||
|
||||
MarkerIndex *marker_index;
|
||||
Node *current_node;
|
||||
Point current_node_position;
|
||||
Point left_ancestor_position;
|
||||
Point right_ancestor_position;
|
||||
std::vector<Point> left_ancestor_position_stack;
|
||||
std::vector<Point> right_ancestor_position_stack;
|
||||
};
|
||||
|
||||
Point get_node_position(const Node *node) const;
|
||||
void delete_node(Node *node);
|
||||
void delete_subtree(Node *node);
|
||||
void bubble_node_up(Node *node);
|
||||
void bubble_node_down(Node *node);
|
||||
void rotate_node_left(Node *pivot);
|
||||
void rotate_node_right(Node *pivot);
|
||||
void
|
||||
get_starting_and_ending_markers_within_subtree(const Node *node,
|
||||
flat_set<MarkerId> *starting,
|
||||
flat_set<MarkerId> *ending);
|
||||
void populate_splice_invalidation_sets(
|
||||
SpliceResult *invalidated, const Node *start_node, const Node *end_node,
|
||||
const flat_set<MarkerId> &starting_inside_splice,
|
||||
const flat_set<MarkerId> &ending_inside_splice);
|
||||
|
||||
std::default_random_engine random_engine;
|
||||
std::uniform_int_distribution<int> random_distribution;
|
||||
Node *root;
|
||||
std::unordered_map<MarkerId, Node *> start_nodes_by_id;
|
||||
std::unordered_map<MarkerId, Node *> end_nodes_by_id;
|
||||
Iterator iterator;
|
||||
flat_set<MarkerId> exclusive_marker_ids;
|
||||
mutable std::unordered_map<const Node *, Point> node_position_cache;
|
||||
};
|
||||
|
||||
#endif // MARKER_INDEX_H_
|
||||
Vendored
+311
@@ -0,0 +1,311 @@
|
||||
#include "compiler/rule.h"
|
||||
#include "compiler/util/hash_combine.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
|
||||
using std::move;
|
||||
using std::vector;
|
||||
using util::hash_combine;
|
||||
|
||||
Rule::Rule(const Rule &other) : blank_(Blank{}), type(BlankType) {
|
||||
*this = other;
|
||||
}
|
||||
|
||||
Rule::Rule(Rule &&other) noexcept : blank_(Blank{}), type(BlankType) {
|
||||
*this = move(other);
|
||||
}
|
||||
|
||||
static void destroy_value(Rule *rule) {
|
||||
switch (rule->type) {
|
||||
case Rule::BlankType:
|
||||
return rule->blank_.~Blank();
|
||||
case Rule::CharacterSetType:
|
||||
return rule->character_set_.~CharacterSet();
|
||||
case Rule::StringType:
|
||||
return rule->string_.~String();
|
||||
case Rule::PatternType:
|
||||
return rule->pattern_.~Pattern();
|
||||
case Rule::NamedSymbolType:
|
||||
return rule->named_symbol_.~NamedSymbol();
|
||||
case Rule::SymbolType:
|
||||
return rule->symbol_.~Symbol();
|
||||
case Rule::ChoiceType:
|
||||
return rule->choice_.~Choice();
|
||||
case Rule::MetadataType:
|
||||
return rule->metadata_.~Metadata();
|
||||
case Rule::RepeatType:
|
||||
return rule->repeat_.~Repeat();
|
||||
case Rule::SeqType:
|
||||
return rule->seq_.~Seq();
|
||||
}
|
||||
}
|
||||
|
||||
Rule &Rule::operator=(const Rule &other) {
|
||||
destroy_value(this);
|
||||
type = other.type;
|
||||
switch (type) {
|
||||
case BlankType:
|
||||
new (&blank_) Blank(other.blank_);
|
||||
break;
|
||||
case CharacterSetType:
|
||||
new (&character_set_) CharacterSet(other.character_set_);
|
||||
break;
|
||||
case StringType:
|
||||
new (&string_) String(other.string_);
|
||||
break;
|
||||
case PatternType:
|
||||
new (&pattern_) Pattern(other.pattern_);
|
||||
break;
|
||||
case NamedSymbolType:
|
||||
new (&named_symbol_) NamedSymbol(other.named_symbol_);
|
||||
break;
|
||||
case SymbolType:
|
||||
new (&symbol_) Symbol(other.symbol_);
|
||||
break;
|
||||
case ChoiceType:
|
||||
new (&choice_) Choice(other.choice_);
|
||||
break;
|
||||
case MetadataType:
|
||||
new (&metadata_) Metadata(other.metadata_);
|
||||
break;
|
||||
case RepeatType:
|
||||
new (&repeat_) Repeat(other.repeat_);
|
||||
break;
|
||||
case SeqType:
|
||||
new (&seq_) Seq(other.seq_);
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Rule &Rule::operator=(Rule &&other) noexcept {
|
||||
destroy_value(this);
|
||||
type = other.type;
|
||||
switch (type) {
|
||||
case BlankType:
|
||||
new (&blank_) Blank(move(other.blank_));
|
||||
break;
|
||||
case CharacterSetType:
|
||||
new (&character_set_) CharacterSet(move(other.character_set_));
|
||||
break;
|
||||
case StringType:
|
||||
new (&string_) String(move(other.string_));
|
||||
break;
|
||||
case PatternType:
|
||||
new (&pattern_) Pattern(move(other.pattern_));
|
||||
break;
|
||||
case NamedSymbolType:
|
||||
new (&named_symbol_) NamedSymbol(move(other.named_symbol_));
|
||||
break;
|
||||
case SymbolType:
|
||||
new (&symbol_) Symbol(move(other.symbol_));
|
||||
break;
|
||||
case ChoiceType:
|
||||
new (&choice_) Choice(move(other.choice_));
|
||||
break;
|
||||
case MetadataType:
|
||||
new (&metadata_) Metadata(move(other.metadata_));
|
||||
break;
|
||||
case RepeatType:
|
||||
new (&repeat_) Repeat(move(other.repeat_));
|
||||
break;
|
||||
case SeqType:
|
||||
new (&seq_) Seq(move(other.seq_));
|
||||
break;
|
||||
}
|
||||
other.type = BlankType;
|
||||
other.blank_ = Blank{};
|
||||
return *this;
|
||||
}
|
||||
|
||||
Rule::~Rule() noexcept { destroy_value(this); }
|
||||
|
||||
bool Rule::operator==(const Rule &other) const {
|
||||
if (type != other.type)
|
||||
return false;
|
||||
switch (type) {
|
||||
case Rule::CharacterSetType:
|
||||
return character_set_ == other.character_set_;
|
||||
case Rule::StringType:
|
||||
return string_ == other.string_;
|
||||
case Rule::PatternType:
|
||||
return pattern_ == other.pattern_;
|
||||
case Rule::NamedSymbolType:
|
||||
return named_symbol_ == other.named_symbol_;
|
||||
case Rule::SymbolType:
|
||||
return symbol_ == other.symbol_;
|
||||
case Rule::ChoiceType:
|
||||
return choice_ == other.choice_;
|
||||
case Rule::MetadataType:
|
||||
return metadata_ == other.metadata_;
|
||||
case Rule::RepeatType:
|
||||
return repeat_ == other.repeat_;
|
||||
case Rule::SeqType:
|
||||
return seq_ == other.seq_;
|
||||
default:
|
||||
return blank_ == other.blank_;
|
||||
}
|
||||
}
|
||||
|
||||
template <> bool Rule::is<Blank>() const { return type == BlankType; }
|
||||
|
||||
template <> bool Rule::is<Symbol>() const { return type == SymbolType; }
|
||||
|
||||
template <> bool Rule::is<Repeat>() const { return type == RepeatType; }
|
||||
|
||||
template <> const Symbol &Rule::get_unchecked<Symbol>() const {
|
||||
return symbol_;
|
||||
}
|
||||
|
||||
static inline void add_choice_element(std::vector<Rule> *elements,
|
||||
const Rule &new_rule) {
|
||||
new_rule.match(
|
||||
[elements](Choice choice) {
|
||||
for (auto &element : choice.elements) {
|
||||
add_choice_element(elements, element);
|
||||
}
|
||||
},
|
||||
|
||||
[elements](auto rule) {
|
||||
for (auto &element : *elements) {
|
||||
if (element == rule)
|
||||
return;
|
||||
}
|
||||
elements->push_back(rule);
|
||||
});
|
||||
}
|
||||
|
||||
Rule Rule::choice(const vector<Rule> &rules) {
|
||||
vector<Rule> elements;
|
||||
for (auto &element : rules) {
|
||||
add_choice_element(&elements, element);
|
||||
}
|
||||
return (elements.size() == 1) ? elements.front() : Choice{elements};
|
||||
}
|
||||
|
||||
Rule Rule::repeat(const Rule &rule) {
|
||||
return rule.is<Repeat>() ? rule : Repeat{rule};
|
||||
}
|
||||
|
||||
Rule Rule::seq(const vector<Rule> &rules) {
|
||||
Rule result;
|
||||
for (const auto &rule : rules) {
|
||||
rule.match([](Blank) {},
|
||||
[&](Metadata metadata) {
|
||||
if (!metadata.rule->is<Blank>()) {
|
||||
result = Seq{result, rule};
|
||||
}
|
||||
},
|
||||
[&](auto) {
|
||||
if (result.is<Blank>()) {
|
||||
result = rule;
|
||||
} else {
|
||||
result = Seq{result, rule};
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace rules
|
||||
} // namespace tree_sitter
|
||||
|
||||
namespace std {
|
||||
|
||||
size_t hash<Symbol>::operator()(const Symbol &symbol) const {
|
||||
auto result = hash<int>()(symbol.index);
|
||||
hash_combine(&result, hash<int>()(symbol.type));
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t hash<NamedSymbol>::operator()(const NamedSymbol &symbol) const {
|
||||
return hash<string>()(symbol.value);
|
||||
}
|
||||
|
||||
size_t hash<Pattern>::operator()(const Pattern &symbol) const {
|
||||
return hash<string>()(symbol.value);
|
||||
}
|
||||
|
||||
size_t hash<String>::operator()(const String &symbol) const {
|
||||
return hash<string>()(symbol.value);
|
||||
}
|
||||
|
||||
size_t hash<CharacterSet>::operator()(const CharacterSet &character_set) const {
|
||||
size_t result = 0;
|
||||
hash_combine(&result, character_set.includes_all);
|
||||
hash_combine(&result, character_set.included_chars.size());
|
||||
for (uint32_t c : character_set.included_chars) {
|
||||
hash_combine(&result, c);
|
||||
}
|
||||
hash_combine(&result, character_set.excluded_chars.size());
|
||||
for (uint32_t c : character_set.excluded_chars) {
|
||||
hash_combine(&result, c);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t hash<Blank>::operator()(const Blank &blank) const { return 0; }
|
||||
|
||||
size_t hash<Choice>::operator()(const Choice &choice) const {
|
||||
size_t result = 0;
|
||||
for (const auto &element : choice.elements) {
|
||||
symmetric_hash_combine(&result, element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t hash<Repeat>::operator()(const Repeat &repeat) const {
|
||||
size_t result = 0;
|
||||
hash_combine(&result, *repeat.rule);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t hash<Seq>::operator()(const Seq &seq) const {
|
||||
size_t result = 0;
|
||||
hash_combine(&result, *seq.left);
|
||||
hash_combine(&result, *seq.right);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t hash<Metadata>::operator()(const Metadata &metadata) const {
|
||||
size_t result = 0;
|
||||
hash_combine(&result, *metadata.rule);
|
||||
hash_combine(&result, metadata.params.precedence);
|
||||
hash_combine<int>(&result, metadata.params.associativity);
|
||||
hash_combine(&result, metadata.params.has_precedence);
|
||||
hash_combine(&result, metadata.params.has_associativity);
|
||||
hash_combine(&result, metadata.params.is_token);
|
||||
hash_combine(&result, metadata.params.is_string);
|
||||
hash_combine(&result, metadata.params.is_active);
|
||||
hash_combine(&result, metadata.params.is_main_token);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t hash<Rule>::operator()(const Rule &rule) const {
|
||||
size_t result = hash<int>()(rule.type);
|
||||
switch (rule.type) {
|
||||
case Rule::CharacterSetType:
|
||||
return result ^ hash<CharacterSet>()(rule.character_set_);
|
||||
case Rule::StringType:
|
||||
return result ^ hash<String>()(rule.string_);
|
||||
case Rule::PatternType:
|
||||
return result ^ hash<Pattern>()(rule.pattern_);
|
||||
case Rule::NamedSymbolType:
|
||||
return result ^ hash<NamedSymbol>()(rule.named_symbol_);
|
||||
case Rule::SymbolType:
|
||||
return result ^ hash<Symbol>()(rule.symbol_);
|
||||
case Rule::ChoiceType:
|
||||
return result ^ hash<Choice>()(rule.choice_);
|
||||
case Rule::MetadataType:
|
||||
return result ^ hash<Metadata>()(rule.metadata_);
|
||||
case Rule::RepeatType:
|
||||
return result ^ hash<Repeat>()(rule.repeat_);
|
||||
case Rule::SeqType:
|
||||
return result ^ hash<Seq>()(rule.seq_);
|
||||
default:
|
||||
return result ^ hash<Blank>()(rule.blank_);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
+1
-1
@@ -28,7 +28,7 @@
|
||||
{
|
||||
"scope": "source.mql5",
|
||||
"file-types": [
|
||||
"mql5",
|
||||
"mq5",
|
||||
"mqh"
|
||||
],
|
||||
"highlights": [
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
================================================
|
||||
template functions vs relational expressions
|
||||
================================================
|
||||
|
||||
T1 a = b < c > d;
|
||||
T2 e = f<T3>(g);
|
||||
int a = std::get<0>(t);
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(init_declarator
|
||||
(identifier)
|
||||
(binary_expression
|
||||
(binary_expression (identifier) (identifier))
|
||||
(identifier))))
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(init_declarator
|
||||
(identifier)
|
||||
(call_expression
|
||||
(template_function (identifier) (template_argument_list
|
||||
(type_descriptor (type_identifier))))
|
||||
(argument_list (identifier)))))
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(init_declarator
|
||||
(identifier)
|
||||
(call_expression
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(template_function
|
||||
(identifier)
|
||||
(template_argument_list (number_literal))))
|
||||
(argument_list (identifier))))))
|
||||
|
||||
=================================================
|
||||
function declarations vs variable initializations
|
||||
=================================================
|
||||
|
||||
// Function declarations
|
||||
T1 a(T2 *b);
|
||||
T3 c(T4 &d, T5 &&e);
|
||||
|
||||
// Variable declarations with initializers
|
||||
T7 f(g.h);
|
||||
T6 i{j};
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(comment)
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list (parameter_declaration (type_identifier) (pointer_declarator (identifier))))))
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration (type_identifier) (reference_declarator (identifier)))
|
||||
(parameter_declaration (type_identifier) (reference_declarator (identifier))))))
|
||||
|
||||
(comment)
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(init_declarator
|
||||
(identifier)
|
||||
(argument_list (field_expression (identifier) (field_identifier)))))
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(init_declarator
|
||||
(identifier)
|
||||
(initializer_list (identifier)))))
|
||||
|
||||
================================================
|
||||
template classes vs relational expressions
|
||||
================================================
|
||||
|
||||
int main() {
|
||||
T1<T2> v1;
|
||||
T1<T2> v2 = v3;
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit (function_definition
|
||||
(primitive_type)
|
||||
(function_declarator (identifier) (parameter_list))
|
||||
(compound_statement
|
||||
(declaration
|
||||
(template_type (type_identifier)
|
||||
(template_argument_list (type_descriptor (type_identifier))))
|
||||
(identifier))
|
||||
(declaration
|
||||
(template_type (type_identifier)
|
||||
(template_argument_list (type_descriptor (type_identifier))))
|
||||
(init_declarator (identifier) (identifier))))))
|
||||
@@ -0,0 +1,607 @@
|
||||
================================================================================
|
||||
Concept definition
|
||||
================================================================================
|
||||
|
||||
template <class T, class U>
|
||||
concept Derived = std::is_base_of<U, T>::value;
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(type_parameter_declaration
|
||||
(type_identifier))
|
||||
(type_parameter_declaration
|
||||
(type_identifier)))
|
||||
(concept_definition
|
||||
(identifier)
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(qualified_identifier
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier))
|
||||
(type_descriptor
|
||||
(type_identifier))))
|
||||
(identifier))))))
|
||||
|
||||
================================================================================
|
||||
Concept definition with requires expression
|
||||
================================================================================
|
||||
|
||||
template<typename T>
|
||||
concept Hashable = requires(T a) {
|
||||
{ std::hash<T>{}(a) } -> std::convertible_to<std::size_t>;
|
||||
};
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(type_parameter_declaration
|
||||
(type_identifier)))
|
||||
(concept_definition
|
||||
(identifier)
|
||||
(requires_expression
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier)
|
||||
(identifier)))
|
||||
(requirement_seq
|
||||
(compound_requirement
|
||||
(call_expression
|
||||
(compound_literal_expression
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier)))))
|
||||
(initializer_list))
|
||||
(argument_list
|
||||
(identifier)))
|
||||
(trailing_return_type
|
||||
(type_descriptor
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(type_identifier))))))))))))))
|
||||
|
||||
================================================================================
|
||||
Requires clauses and expressions
|
||||
================================================================================
|
||||
|
||||
template<typename T>
|
||||
void f(T&&) requires Eq<T>; // can appear as the last element of a function declarator
|
||||
|
||||
template<typename T> requires Addable<T> // or right after a template parameter list
|
||||
T add(T a, T b) { return a + b; }
|
||||
|
||||
template<typename T>
|
||||
concept Addable = requires (T x) { x + x; }; // requires-expression
|
||||
|
||||
template<typename T>
|
||||
requires requires (T x) { x + x; } // ad-hoc constraint, note keyword used twice
|
||||
T add(T a, T b) { return a + b; }
|
||||
|
||||
template<typename T>
|
||||
requires (!std::is_same_v<T, bool>) // parenthesized expressions are allowed
|
||||
void f(T);
|
||||
|
||||
template<typename T> requires Addable<T> && Subtractable<T> // conjunctions
|
||||
T f(T);
|
||||
|
||||
template<typename T> requires Addable<T> || Subtractable<T> // disjunctions
|
||||
T f(T);
|
||||
|
||||
template<typename T> requires false || true // boolean literals
|
||||
T f(T);
|
||||
|
||||
template<typename... T> requires (... && Addable<T>) // fold expressions
|
||||
T f(T);
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(type_parameter_declaration
|
||||
(type_identifier)))
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier)
|
||||
(abstract_reference_declarator)))
|
||||
(requires_clause
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier))))))))
|
||||
(comment)
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(type_parameter_declaration
|
||||
(type_identifier)))
|
||||
(requires_clause
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier)))))
|
||||
(comment)
|
||||
(function_definition
|
||||
(type_identifier)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier)
|
||||
(identifier))
|
||||
(parameter_declaration
|
||||
(type_identifier)
|
||||
(identifier))))
|
||||
(compound_statement
|
||||
(return_statement
|
||||
(binary_expression
|
||||
(identifier)
|
||||
(identifier))))))
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(type_parameter_declaration
|
||||
(type_identifier)))
|
||||
(concept_definition
|
||||
(identifier)
|
||||
(requires_expression
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier)
|
||||
(identifier)))
|
||||
(requirement_seq
|
||||
(simple_requirement
|
||||
(binary_expression
|
||||
(identifier)
|
||||
(identifier)))))))
|
||||
(comment)
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(type_parameter_declaration
|
||||
(type_identifier)))
|
||||
(requires_clause
|
||||
(requires_expression
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier)
|
||||
(identifier)))
|
||||
(requirement_seq
|
||||
(simple_requirement
|
||||
(binary_expression
|
||||
(identifier)
|
||||
(identifier))))))
|
||||
(comment)
|
||||
(function_definition
|
||||
(type_identifier)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier)
|
||||
(identifier))
|
||||
(parameter_declaration
|
||||
(type_identifier)
|
||||
(identifier))))
|
||||
(compound_statement
|
||||
(return_statement
|
||||
(binary_expression
|
||||
(identifier)
|
||||
(identifier))))))
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(type_parameter_declaration
|
||||
(type_identifier)))
|
||||
(requires_clause
|
||||
(unary_expression
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(template_function
|
||||
(identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier))
|
||||
(type_descriptor
|
||||
(primitive_type)))))))
|
||||
(comment)
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier))))))
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(type_parameter_declaration
|
||||
(type_identifier)))
|
||||
(requires_clause
|
||||
(constraint_conjunction
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier))))
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier))))))
|
||||
(comment)
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier))))))
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(type_parameter_declaration
|
||||
(type_identifier)))
|
||||
(requires_clause
|
||||
(constraint_disjunction
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier))))
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier))))))
|
||||
(comment)
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier))))))
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(type_parameter_declaration
|
||||
(type_identifier)))
|
||||
(requires_clause
|
||||
(constraint_disjunction
|
||||
(false)
|
||||
(true)))
|
||||
(comment)
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier))))))
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(variadic_type_parameter_declaration
|
||||
(type_identifier)))
|
||||
(requires_clause
|
||||
(fold_expression
|
||||
(template_function
|
||||
(identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier))))))
|
||||
(comment)
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier)))))))
|
||||
|
||||
================================================================================
|
||||
Compound requirements
|
||||
================================================================================
|
||||
|
||||
template<typename T> concept C2 =
|
||||
requires(T x) {
|
||||
{*x} -> std::convertible_to<typename T::inner>; // the expression *x must be valid
|
||||
// AND the type T::inner must be valid
|
||||
// AND the result of *x must be convertible to T::inner
|
||||
{x + 1} -> std::same_as<int>; // the expression x + 1 must be valid
|
||||
// AND std::same_as<decltype((x + 1)), int> must be satisfied
|
||||
// i.e., (x + 1) must be a prvalue of type int
|
||||
{x * 1} -> std::convertible_to<T>; // the expression x * 1 must be valid
|
||||
// AND its result must be convertible to T
|
||||
};
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(type_parameter_declaration
|
||||
(type_identifier)))
|
||||
(concept_definition
|
||||
(identifier)
|
||||
(requires_expression
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier)
|
||||
(identifier)))
|
||||
(requirement_seq
|
||||
(compound_requirement
|
||||
(pointer_expression
|
||||
(identifier))
|
||||
(trailing_return_type
|
||||
(type_descriptor
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(dependent_type
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(type_identifier))))))))))
|
||||
(comment)
|
||||
(comment)
|
||||
(comment)
|
||||
(compound_requirement
|
||||
(binary_expression
|
||||
(identifier)
|
||||
(number_literal))
|
||||
(trailing_return_type
|
||||
(type_descriptor
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(primitive_type))))))))
|
||||
(comment)
|
||||
(comment)
|
||||
(comment)
|
||||
(compound_requirement
|
||||
(binary_expression
|
||||
(identifier)
|
||||
(number_literal))
|
||||
(trailing_return_type
|
||||
(type_descriptor
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier))))))))
|
||||
(comment)
|
||||
(comment))))))
|
||||
|
||||
================================================================================
|
||||
Nested requirements
|
||||
================================================================================
|
||||
|
||||
template <class T>
|
||||
concept Semiregular = DefaultConstructible<T> &&
|
||||
CopyConstructible<T> && Destructible<T> && CopyAssignable<T> &&
|
||||
requires(T a, size_t n) {
|
||||
requires Same<T*, decltype(&a)>; // nested: "Same<...> evaluates to true"
|
||||
{ a.~T() } noexcept; // compound: "a.~T()" is a valid expression that doesn't throw
|
||||
requires Same<T*, decltype(new T)>; // nested: "Same<...> evaluates to true"
|
||||
requires Same<T*, decltype(new T[n])>; // nested
|
||||
{ delete new T }; // compound
|
||||
{ delete new T[n] }; // compound
|
||||
};
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(translation_unit
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(type_parameter_declaration
|
||||
(type_identifier)))
|
||||
(concept_definition
|
||||
(identifier)
|
||||
(binary_expression
|
||||
(binary_expression
|
||||
(binary_expression
|
||||
(binary_expression
|
||||
(template_function
|
||||
(identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier))))
|
||||
(template_function
|
||||
(identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier)))))
|
||||
(template_function
|
||||
(identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier)))))
|
||||
(template_function
|
||||
(identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier)))))
|
||||
(requires_expression
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier)
|
||||
(identifier))
|
||||
(parameter_declaration
|
||||
(primitive_type)
|
||||
(identifier)))
|
||||
(requirement_seq
|
||||
(simple_requirement
|
||||
(requires_clause
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier)
|
||||
(abstract_pointer_declarator))
|
||||
(type_descriptor
|
||||
(decltype
|
||||
(pointer_expression
|
||||
(identifier))))))))
|
||||
(comment)
|
||||
(compound_requirement
|
||||
(call_expression
|
||||
(field_expression
|
||||
(identifier)
|
||||
(destructor_name
|
||||
(identifier)))
|
||||
(argument_list)))
|
||||
(comment)
|
||||
(simple_requirement
|
||||
(requires_clause
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier)
|
||||
(abstract_pointer_declarator))
|
||||
(type_descriptor
|
||||
(decltype
|
||||
(new_expression
|
||||
(type_identifier))))))))
|
||||
(comment)
|
||||
(simple_requirement
|
||||
(requires_clause
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier)
|
||||
(abstract_pointer_declarator))
|
||||
(type_descriptor
|
||||
(decltype
|
||||
(new_expression
|
||||
(type_identifier)
|
||||
(new_declarator
|
||||
(identifier)))))))))
|
||||
(comment)
|
||||
(compound_requirement
|
||||
(delete_expression
|
||||
(new_expression
|
||||
(type_identifier))))
|
||||
(comment)
|
||||
(compound_requirement
|
||||
(delete_expression
|
||||
(new_expression
|
||||
(type_identifier)
|
||||
(new_declarator
|
||||
(identifier)))))
|
||||
(comment)))))))
|
||||
|
||||
================================================================================
|
||||
Constraints
|
||||
================================================================================
|
||||
|
||||
template <EqualityComparable T>
|
||||
void f(const T&); // constrained function template declaration
|
||||
|
||||
void f(const EqualityComparable auto&); // constrained function template declaration
|
||||
|
||||
Sortable auto foo = f();
|
||||
Sortable<T> auto bar = g();
|
||||
NS::Concept<T> auto baz = h();
|
||||
|
||||
Sortable decltype(auto) foo = i();
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(parameter_declaration
|
||||
(type_identifier)
|
||||
(identifier)))
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_qualifier)
|
||||
(type_identifier)
|
||||
(abstract_reference_declarator))))))
|
||||
(comment)
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration
|
||||
(type_qualifier)
|
||||
(placeholder_type_specifier
|
||||
(type_identifier)
|
||||
(auto))
|
||||
(abstract_reference_declarator)))))
|
||||
(comment)
|
||||
(declaration
|
||||
(placeholder_type_specifier
|
||||
(type_identifier)
|
||||
(auto))
|
||||
(init_declarator
|
||||
(identifier)
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list))))
|
||||
(declaration
|
||||
(placeholder_type_specifier
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier))))
|
||||
(auto))
|
||||
(init_declarator
|
||||
(identifier)
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list))))
|
||||
(declaration
|
||||
(placeholder_type_specifier
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier)))))
|
||||
(auto))
|
||||
(init_declarator
|
||||
(identifier)
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list))))
|
||||
(declaration
|
||||
(placeholder_type_specifier
|
||||
(type_identifier)
|
||||
(decltype
|
||||
(auto)))
|
||||
(init_declarator
|
||||
(identifier)
|
||||
(call_expression
|
||||
(identifier)
|
||||
(argument_list)))))
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,243 @@
|
||||
=====================================
|
||||
Scoped function definitions
|
||||
=====================================
|
||||
|
||||
int T::foo() { return 1; }
|
||||
int T::foo() const { return 0; }
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(qualified_identifier (namespace_identifier) (identifier))
|
||||
(parameter_list))
|
||||
(compound_statement (return_statement (number_literal))))
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(qualified_identifier (namespace_identifier) (identifier))
|
||||
(parameter_list)
|
||||
(type_qualifier))
|
||||
(compound_statement (return_statement (number_literal)))))
|
||||
|
||||
=====================================
|
||||
Constructor definitions
|
||||
=====================================
|
||||
|
||||
T::T() {}
|
||||
|
||||
T::T() : f1(0), f2(1, 2) {
|
||||
puts("HI");
|
||||
}
|
||||
|
||||
T::T() : Base<T>() {}
|
||||
|
||||
T::T() try : f1(0) {} catch(...) {}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(function_declarator
|
||||
(qualified_identifier (namespace_identifier) (identifier))
|
||||
(parameter_list))
|
||||
(compound_statement))
|
||||
(function_definition
|
||||
(function_declarator
|
||||
(qualified_identifier (namespace_identifier) (identifier))
|
||||
(parameter_list))
|
||||
(field_initializer_list
|
||||
(field_initializer (field_identifier) (argument_list (number_literal)))
|
||||
(field_initializer (field_identifier) (argument_list (number_literal) (number_literal))))
|
||||
(compound_statement
|
||||
(expression_statement (call_expression (identifier) (argument_list (string_literal))))))
|
||||
(function_definition
|
||||
(function_declarator
|
||||
(qualified_identifier (namespace_identifier) (identifier))
|
||||
(parameter_list))
|
||||
(field_initializer_list
|
||||
(field_initializer
|
||||
(template_method
|
||||
(field_identifier)
|
||||
(template_argument_list (type_descriptor (type_identifier))))
|
||||
(argument_list)))
|
||||
(compound_statement))
|
||||
(function_definition
|
||||
(function_declarator
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(identifier))
|
||||
(parameter_list))
|
||||
(try_statement
|
||||
(field_initializer_list
|
||||
(field_initializer
|
||||
(field_identifier)
|
||||
(argument_list
|
||||
(number_literal))))
|
||||
(compound_statement)
|
||||
(catch_clause
|
||||
(parameter_list)
|
||||
(compound_statement)))))
|
||||
|
||||
=====================================
|
||||
Explicit constructor definitions
|
||||
=====================================
|
||||
|
||||
class C {
|
||||
explicit C(int f) : f_(f) {}
|
||||
|
||||
private:
|
||||
int f_;
|
||||
};
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(class_specifier
|
||||
(type_identifier)
|
||||
(field_declaration_list
|
||||
(function_definition
|
||||
(explicit_function_specifier)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list (parameter_declaration (primitive_type) (identifier))))
|
||||
(field_initializer_list
|
||||
(field_initializer (field_identifier) (argument_list (identifier))))
|
||||
(compound_statement))
|
||||
(access_specifier)
|
||||
(field_declaration (primitive_type) (field_identifier)))))
|
||||
|
||||
=====================================
|
||||
Explicit constructor declaration
|
||||
=====================================
|
||||
|
||||
class C {
|
||||
explicit C(int f);
|
||||
explicit(true) C(long f);
|
||||
};
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(class_specifier
|
||||
(type_identifier)
|
||||
(field_declaration_list
|
||||
(declaration
|
||||
(explicit_function_specifier)
|
||||
(function_declarator (identifier) (parameter_list (parameter_declaration (primitive_type) (identifier)))))
|
||||
(declaration
|
||||
(explicit_function_specifier (true))
|
||||
(function_declarator (identifier) (parameter_list (parameter_declaration (sized_type_specifier) (identifier))))))))
|
||||
|
||||
=====================================
|
||||
Default and deleted methods
|
||||
=====================================
|
||||
|
||||
class A : public B {
|
||||
A() = default;
|
||||
A(A &&) = delete;
|
||||
void f() = delete;
|
||||
A& operator=(const A&) = default;
|
||||
A& operator=(A&&) = delete;
|
||||
};
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(class_specifier
|
||||
(type_identifier)
|
||||
(base_class_clause (type_identifier))
|
||||
(field_declaration_list
|
||||
(function_definition
|
||||
(function_declarator (identifier) (parameter_list))
|
||||
(default_method_clause))
|
||||
(function_definition
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list (parameter_declaration (type_identifier) (abstract_reference_declarator))))
|
||||
(delete_method_clause))
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator (field_identifier) (parameter_list)) (delete_method_clause))
|
||||
(function_definition
|
||||
(type_identifier)
|
||||
(reference_declarator
|
||||
(function_declarator
|
||||
(operator_name)
|
||||
(parameter_list (parameter_declaration (type_qualifier) (type_identifier) (abstract_reference_declarator)))))
|
||||
(default_method_clause))
|
||||
(function_definition
|
||||
(type_identifier)
|
||||
(reference_declarator
|
||||
(function_declarator
|
||||
(operator_name)
|
||||
(parameter_list (parameter_declaration (type_identifier) (abstract_reference_declarator)))))
|
||||
(delete_method_clause)))))
|
||||
|
||||
=====================================
|
||||
Destructor definitions
|
||||
=====================================
|
||||
|
||||
~T() {}
|
||||
T::~T() {}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(function_declarator (destructor_name (identifier)) (parameter_list))
|
||||
(compound_statement))
|
||||
(function_definition
|
||||
(function_declarator
|
||||
(qualified_identifier (namespace_identifier) (destructor_name (identifier))) (parameter_list))
|
||||
(compound_statement)))
|
||||
|
||||
=====================================
|
||||
Function-try-block definitions
|
||||
=====================================
|
||||
|
||||
void foo() try {} catch(...) {}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(try_statement
|
||||
(compound_statement)
|
||||
(catch_clause
|
||||
(parameter_list)
|
||||
(compound_statement)))))
|
||||
|
||||
|
||||
=====================================
|
||||
Conversion operator definitions
|
||||
=====================================
|
||||
|
||||
T::operator int() try { throw 1; } catch (...) { return 2; }
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(operator_cast
|
||||
(primitive_type)
|
||||
(abstract_function_declarator
|
||||
(parameter_list))))
|
||||
(try_statement
|
||||
(compound_statement
|
||||
(throw_statement
|
||||
(number_literal)))
|
||||
(catch_clause
|
||||
(parameter_list)
|
||||
(compound_statement
|
||||
(return_statement
|
||||
(number_literal)))))))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
================================
|
||||
declaration specs
|
||||
================================
|
||||
|
||||
struct __declspec(dllexport) s2
|
||||
{
|
||||
};
|
||||
|
||||
union __declspec(noinline) u2 {
|
||||
};
|
||||
|
||||
class __declspec(uuid) u2 {
|
||||
};
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(struct_specifier
|
||||
(ms_declspec_modifier
|
||||
(identifier))
|
||||
name: (type_identifier)
|
||||
body: (field_declaration_list))
|
||||
(union_specifier
|
||||
(ms_declspec_modifier
|
||||
(identifier))
|
||||
name: (type_identifier)
|
||||
body: (field_declaration_list))
|
||||
(class_specifier
|
||||
(ms_declspec_modifier
|
||||
(identifier))
|
||||
name: (type_identifier)
|
||||
body: (field_declaration_list)))
|
||||
@@ -0,0 +1,433 @@
|
||||
===========================================
|
||||
Returning braced initializer lists
|
||||
===========================================
|
||||
|
||||
T main() {
|
||||
return {0, 5};
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(type_identifier)
|
||||
(function_declarator (identifier) (parameter_list))
|
||||
(compound_statement
|
||||
(return_statement (initializer_list (number_literal) (number_literal))))))
|
||||
|
||||
===========================================
|
||||
Range-based for loops
|
||||
===========================================
|
||||
|
||||
T main() {
|
||||
for (Value &value : values) {
|
||||
cout << value;
|
||||
}
|
||||
|
||||
for (const auto &value : values) {
|
||||
cout << value;
|
||||
}
|
||||
|
||||
for (const auto &value : {1, 2, 3}) {
|
||||
cout << value;
|
||||
}
|
||||
|
||||
for (auto n = v.size(); auto i : v) {
|
||||
cout << --n + i << ' ';
|
||||
}
|
||||
|
||||
for (using elem_t = T::value_type; elem_t i : v) {
|
||||
cout << --n + i << ' ';
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
type: (type_identifier)
|
||||
declarator: (function_declarator
|
||||
declarator: (identifier)
|
||||
parameters: (parameter_list))
|
||||
body: (compound_statement
|
||||
(for_range_loop
|
||||
type: (type_identifier)
|
||||
declarator: (reference_declarator (identifier))
|
||||
right: (identifier)
|
||||
body: (compound_statement
|
||||
(expression_statement (binary_expression
|
||||
left: (identifier)
|
||||
right: (identifier)))))
|
||||
(for_range_loop
|
||||
(type_qualifier)
|
||||
type: (placeholder_type_specifier (auto))
|
||||
declarator: (reference_declarator (identifier))
|
||||
right: (identifier)
|
||||
body: (compound_statement
|
||||
(expression_statement (binary_expression
|
||||
left: (identifier)
|
||||
right: (identifier)))))
|
||||
(for_range_loop
|
||||
(type_qualifier)
|
||||
type: (placeholder_type_specifier (auto))
|
||||
declarator: (reference_declarator (identifier))
|
||||
right: (initializer_list (number_literal) (number_literal) (number_literal))
|
||||
body: (compound_statement
|
||||
(expression_statement (binary_expression
|
||||
left: (identifier)
|
||||
right: (identifier)))))
|
||||
(for_range_loop
|
||||
initializer: (init_statement
|
||||
(declaration
|
||||
type: (placeholder_type_specifier (auto))
|
||||
declarator: (init_declarator
|
||||
declarator: (identifier)
|
||||
value: (call_expression
|
||||
function: (field_expression
|
||||
argument: (identifier)
|
||||
field: (field_identifier))
|
||||
arguments: (argument_list)))))
|
||||
type: (placeholder_type_specifier (auto))
|
||||
declarator: (identifier)
|
||||
right: (identifier)
|
||||
body: (compound_statement
|
||||
(expression_statement
|
||||
(binary_expression
|
||||
left: (binary_expression
|
||||
left: (identifier)
|
||||
right: (binary_expression
|
||||
left: (update_expression
|
||||
argument: (identifier))
|
||||
right: (identifier)))
|
||||
right: (char_literal)))))
|
||||
(for_range_loop
|
||||
initializer: (init_statement
|
||||
(alias_declaration
|
||||
name: (type_identifier)
|
||||
type: (type_descriptor
|
||||
type: (qualified_identifier
|
||||
scope: (namespace_identifier)
|
||||
name: (type_identifier)))))
|
||||
type: (type_identifier)
|
||||
declarator: (identifier)
|
||||
right: (identifier)
|
||||
body: (compound_statement
|
||||
(expression_statement
|
||||
(binary_expression
|
||||
left: (binary_expression
|
||||
left: (identifier)
|
||||
right: (binary_expression
|
||||
left: (update_expression
|
||||
argument: (identifier))
|
||||
right: (identifier)))
|
||||
right: (char_literal))))))))
|
||||
|
||||
===========================================
|
||||
Constexpr if statements
|
||||
===========================================
|
||||
|
||||
T f() {
|
||||
if constexpr (std::is_pointer_v<T>)
|
||||
return *t;
|
||||
else
|
||||
return t;
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
type: (type_identifier)
|
||||
declarator: (function_declarator
|
||||
declarator: (identifier)
|
||||
parameters: (parameter_list))
|
||||
body: (compound_statement
|
||||
(if_statement
|
||||
condition: (condition_clause
|
||||
value: (qualified_identifier
|
||||
scope: (namespace_identifier)
|
||||
name: (template_function
|
||||
name: (identifier)
|
||||
arguments: (template_argument_list
|
||||
(type_descriptor type: (type_identifier))))))
|
||||
consequence: (return_statement
|
||||
(pointer_expression argument: (identifier)))
|
||||
alternative: (return_statement (identifier))))))
|
||||
|
||||
=====================================
|
||||
If statements with declarations
|
||||
====================================
|
||||
|
||||
void f() {
|
||||
if (const int x = foo()) { }
|
||||
if (const int x { foo() }) { }
|
||||
if (const int x = foo(); x != 0) { }
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
type: (primitive_type)
|
||||
declarator: (function_declarator
|
||||
declarator: (identifier)
|
||||
parameters: (parameter_list))
|
||||
body: (compound_statement
|
||||
(if_statement
|
||||
condition: (condition_clause
|
||||
value: (declaration
|
||||
(type_qualifier)
|
||||
type: (primitive_type)
|
||||
declarator: (identifier)
|
||||
value: (call_expression
|
||||
function: (identifier)
|
||||
arguments: (argument_list))))
|
||||
consequence: (compound_statement))
|
||||
(if_statement
|
||||
condition: (condition_clause
|
||||
value: (declaration
|
||||
(type_qualifier)
|
||||
type: (primitive_type)
|
||||
declarator: (identifier)
|
||||
value: (initializer_list (call_expression function: (identifier) arguments: (argument_list)))))
|
||||
consequence: (compound_statement))
|
||||
(if_statement
|
||||
condition: (condition_clause
|
||||
initializer: (init_statement
|
||||
(declaration
|
||||
(type_qualifier)
|
||||
type: (primitive_type)
|
||||
declarator: (init_declarator
|
||||
declarator: (identifier)
|
||||
value: (call_expression function: (identifier) arguments: (argument_list)))))
|
||||
value: (binary_expression left: (identifier) right: (number_literal)))
|
||||
consequence: (compound_statement)))))
|
||||
|
||||
===========================================
|
||||
Try/catch statements
|
||||
===========================================
|
||||
|
||||
void main() {
|
||||
try {
|
||||
f();
|
||||
} catch (const std::overflow_error) {
|
||||
// f() throws std::overflow_error (same type rule)
|
||||
} catch (const exception &e) {
|
||||
// f() throws std::logic_error (base class rule)
|
||||
} catch (...) {
|
||||
// f() throws std::string or int or any other unrelated type
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator (identifier) (parameter_list))
|
||||
(compound_statement
|
||||
(try_statement
|
||||
(compound_statement
|
||||
(expression_statement (call_expression (identifier) (argument_list))))
|
||||
(catch_clause
|
||||
(parameter_list (parameter_declaration (type_qualifier) (qualified_identifier (namespace_identifier) (type_identifier))))
|
||||
(compound_statement (comment)))
|
||||
(catch_clause
|
||||
(parameter_list (parameter_declaration (type_qualifier) (type_identifier) (reference_declarator (identifier))))
|
||||
(compound_statement (comment)))
|
||||
(catch_clause
|
||||
(parameter_list)
|
||||
(compound_statement (comment)))))))
|
||||
|
||||
===========================================
|
||||
Throw statements
|
||||
===========================================
|
||||
|
||||
void main() {
|
||||
throw e;
|
||||
throw x + 1;
|
||||
throw "exception";
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list))
|
||||
(compound_statement
|
||||
(throw_statement (identifier))
|
||||
(throw_statement (binary_expression (identifier) (number_literal)))
|
||||
(throw_statement (string_literal)))))
|
||||
|
||||
===========================================
|
||||
Noexcept specifier
|
||||
===========================================
|
||||
|
||||
void foo() noexcept;
|
||||
void foo() noexcept(true);
|
||||
template<class T> T foo() noexcept(sizeof(T) < 4);
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(function_declarator (identifier) (parameter_list)
|
||||
(noexcept)))
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(function_declarator (identifier) (parameter_list)
|
||||
(noexcept (true))))
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(type_parameter_declaration (type_identifier)))
|
||||
(declaration
|
||||
(type_identifier)
|
||||
(function_declarator (identifier) (parameter_list)
|
||||
(noexcept
|
||||
(binary_expression (sizeof_expression (parenthesized_expression (identifier))) (number_literal)))))))
|
||||
|
||||
===========================================
|
||||
Throw specifier
|
||||
===========================================
|
||||
|
||||
void foo() throw();
|
||||
void foo() throw(int);
|
||||
void foo() throw(std::string, char *);
|
||||
void foo() throw(float) { }
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(function_declarator (identifier) (parameter_list)
|
||||
(throw_specifier)))
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(function_declarator (identifier) (parameter_list)
|
||||
(throw_specifier (type_descriptor (primitive_type)))))
|
||||
(declaration
|
||||
(primitive_type)
|
||||
(function_declarator (identifier) (parameter_list)
|
||||
(throw_specifier
|
||||
(type_descriptor (qualified_identifier (namespace_identifier) (type_identifier)))
|
||||
(type_descriptor (primitive_type) (abstract_pointer_declarator)))))
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator (identifier) (parameter_list)
|
||||
(throw_specifier (type_descriptor (primitive_type))))
|
||||
(compound_statement)))
|
||||
|
||||
===========================================
|
||||
Assignment
|
||||
===========================================
|
||||
|
||||
a::b::c = 1;
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(expression_statement
|
||||
(assignment_expression
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(identifier)))
|
||||
(number_literal))))
|
||||
|
||||
=========================================
|
||||
Attributes
|
||||
=========================================
|
||||
|
||||
void f() {
|
||||
[[a]] switch (b) {
|
||||
[[c]] case 1: {}
|
||||
}
|
||||
[[a]] while (true) {}
|
||||
[[a]] if (true) {}
|
||||
[[a]] for (auto x : y) {}
|
||||
[[a]] for (;;) {}
|
||||
[[a]] return;
|
||||
[[a]] a;
|
||||
[[a]];
|
||||
[[a]] label: {}
|
||||
[[a]] goto label;
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition (primitive_type)
|
||||
(function_declarator (identifier) (parameter_list))
|
||||
(compound_statement
|
||||
(attributed_statement (attribute_declaration (attribute (identifier)))
|
||||
(switch_statement
|
||||
(condition_clause (identifier))
|
||||
(compound_statement
|
||||
(attributed_statement (attribute_declaration (attribute (identifier)))
|
||||
(case_statement (number_literal) (compound_statement))))))
|
||||
(attributed_statement (attribute_declaration (attribute (identifier))) (while_statement (condition_clause (true)) (compound_statement)))
|
||||
(attributed_statement (attribute_declaration (attribute (identifier))) (if_statement (condition_clause (true)) (compound_statement)))
|
||||
(attributed_statement (attribute_declaration (attribute (identifier))) (for_range_loop (placeholder_type_specifier (auto)) (identifier) (identifier) (compound_statement)))
|
||||
(attributed_statement (attribute_declaration (attribute (identifier))) (for_statement (compound_statement)))
|
||||
(attributed_statement (attribute_declaration (attribute (identifier))) (return_statement))
|
||||
(attributed_statement (attribute_declaration (attribute (identifier))) (expression_statement (identifier)))
|
||||
(attributed_statement (attribute_declaration (attribute (identifier))) (expression_statement))
|
||||
(attributed_statement (attribute_declaration (attribute (identifier))) (labeled_statement (statement_identifier) (compound_statement)))
|
||||
(attributed_statement (attribute_declaration (attribute (identifier))) (goto_statement (statement_identifier))))))
|
||||
|
||||
===========================================
|
||||
Coroutines
|
||||
===========================================
|
||||
|
||||
co_return 1;
|
||||
co_return;
|
||||
co_yield 1;
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(co_return_statement
|
||||
(number_literal))
|
||||
(co_return_statement)
|
||||
(co_yield_statement
|
||||
(number_literal)))
|
||||
|
||||
|
||||
===========================================
|
||||
Switch statements
|
||||
===========================================
|
||||
|
||||
void foo(int a) {
|
||||
switch (a) {
|
||||
case 1:
|
||||
for (auto i : vec) {}
|
||||
case 2:
|
||||
try {
|
||||
// do something
|
||||
} catch(...) {}
|
||||
throw 1;
|
||||
case 3:
|
||||
co_return;
|
||||
default:
|
||||
co_yield a;
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition (primitive_type)
|
||||
(function_declarator (identifier) (parameter_list (parameter_declaration (primitive_type) (identifier))))
|
||||
(compound_statement
|
||||
(switch_statement (condition_clause (identifier))
|
||||
(compound_statement
|
||||
(case_statement (number_literal) (for_range_loop (placeholder_type_specifier (auto)) (identifier) (identifier) (compound_statement)))
|
||||
(case_statement (number_literal) (try_statement (compound_statement (comment)) (catch_clause (parameter_list) (compound_statement))) (throw_statement (number_literal)))
|
||||
(case_statement (number_literal) (co_return_statement))
|
||||
(case_statement (co_yield_statement (identifier))))))))
|
||||
@@ -0,0 +1,177 @@
|
||||
==========================================
|
||||
The auto type
|
||||
==========================================
|
||||
|
||||
void foo() {
|
||||
auto x = 1;
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(primitive_type)
|
||||
(function_declarator (identifier) (parameter_list))
|
||||
(compound_statement
|
||||
(declaration (placeholder_type_specifier (auto)) (init_declarator (identifier) (number_literal))))))
|
||||
|
||||
==========================================
|
||||
Namespaced types
|
||||
==========================================
|
||||
|
||||
std::string my_string;
|
||||
std::vector<int>::size_typ my_string;
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(declaration
|
||||
(qualified_identifier (namespace_identifier) (type_identifier))
|
||||
(identifier))
|
||||
(declaration
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(qualified_identifier
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list (type_descriptor (primitive_type))))
|
||||
(type_identifier)))
|
||||
(identifier)))
|
||||
|
||||
==========================================
|
||||
Dependent type names
|
||||
==========================================
|
||||
|
||||
template<typename T>
|
||||
struct X : B<T>
|
||||
{
|
||||
typename T::A* pa;
|
||||
};
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(template_declaration
|
||||
(template_parameter_list (type_parameter_declaration (type_identifier)))
|
||||
(struct_specifier
|
||||
(type_identifier)
|
||||
(base_class_clause
|
||||
(template_type (type_identifier) (template_argument_list (type_descriptor (type_identifier)))))
|
||||
(field_declaration_list
|
||||
(field_declaration
|
||||
(dependent_type (qualified_identifier (namespace_identifier) (type_identifier)))
|
||||
(pointer_declarator (field_identifier)))))))
|
||||
|
||||
==========================================
|
||||
Template types with empty argument lists
|
||||
==========================================
|
||||
|
||||
use_future_t<> use_future;
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(declaration (template_type (type_identifier) (template_argument_list)) (identifier)))
|
||||
|
||||
================================
|
||||
Function types as template arguments
|
||||
================================
|
||||
|
||||
typedef std::function<T(int)> MyFunc;
|
||||
typedef std::function<void(int)> b;
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(type_definition
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(type_identifier)
|
||||
(abstract_function_declarator (parameter_list
|
||||
(parameter_declaration (primitive_type))))))))
|
||||
(type_identifier))
|
||||
(type_definition
|
||||
(qualified_identifier
|
||||
(namespace_identifier)
|
||||
(template_type
|
||||
(type_identifier)
|
||||
(template_argument_list
|
||||
(type_descriptor
|
||||
(primitive_type)
|
||||
(abstract_function_declarator (parameter_list
|
||||
(parameter_declaration (primitive_type))))))))
|
||||
(type_identifier)))
|
||||
|
||||
====================================================
|
||||
Decltype
|
||||
====================================================
|
||||
|
||||
decltype(A) x;
|
||||
decltype(B) foo(void x, decltype(C) y);
|
||||
template<typename T, typename U> auto add(T t, U u) -> decltype(t + u);
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(declaration
|
||||
(decltype (identifier))
|
||||
(identifier))
|
||||
(declaration
|
||||
(decltype (identifier))
|
||||
(function_declarator (identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration (primitive_type) (identifier))
|
||||
(parameter_declaration (decltype (identifier)) (identifier)))))
|
||||
(template_declaration
|
||||
(template_parameter_list
|
||||
(type_parameter_declaration (type_identifier)) (type_parameter_declaration (type_identifier)))
|
||||
(declaration
|
||||
(placeholder_type_specifier (auto))
|
||||
(function_declarator
|
||||
(identifier)
|
||||
(parameter_list
|
||||
(parameter_declaration (type_identifier) (identifier))
|
||||
(parameter_declaration (type_identifier) (identifier)))
|
||||
(trailing_return_type
|
||||
(type_descriptor
|
||||
(decltype (binary_expression (identifier) (identifier)))))))))
|
||||
|
||||
====================================================
|
||||
Trailing return type
|
||||
====================================================
|
||||
|
||||
auto a::foo() const -> const A<B>& {}
|
||||
auto b::foo() const -> A<B> const& {}
|
||||
|
||||
---
|
||||
|
||||
(translation_unit
|
||||
(function_definition
|
||||
(placeholder_type_specifier (auto))
|
||||
(function_declarator
|
||||
(qualified_identifier (namespace_identifier) (identifier))
|
||||
(parameter_list)
|
||||
(type_qualifier)
|
||||
(trailing_return_type
|
||||
(type_descriptor
|
||||
(type_qualifier)
|
||||
(template_type (type_identifier) (template_argument_list (type_descriptor (type_identifier))))
|
||||
(abstract_reference_declarator))))
|
||||
(compound_statement))
|
||||
(function_definition
|
||||
(placeholder_type_specifier (auto))
|
||||
(function_declarator
|
||||
(qualified_identifier (namespace_identifier) (identifier))
|
||||
(parameter_list)
|
||||
(type_qualifier)
|
||||
(trailing_return_type
|
||||
(type_descriptor
|
||||
(template_type (type_identifier) (template_argument_list (type_descriptor (type_identifier))))
|
||||
(type_qualifier)
|
||||
(abstract_reference_declarator))))
|
||||
(compound_statement))
|
||||
)
|
||||
Reference in New Issue
Block a user