conceptclang : an implementation of c++ concepts in clang

32
ConceptClang: An Implementation of C++ Concepts in Clang Larisse Voufo, Marcin Zalewski, and Andrew Lumsdaine Open Systems Lab, Indiana University

Upload: najila

Post on 25-Feb-2016

104 views

Category:

Documents


0 download

DESCRIPTION

ConceptClang : An Implementation of C++ Concepts in Clang. Larisse Voufo , Marcin Zalewski , and Andrew Lumsdaine Open Systems Lab, Indiana University. Designing Concepts in C++. Concepts are the basis of generic programming C++ does not have concepts language feature - PowerPoint PPT Presentation

TRANSCRIPT

ConceptClang: An Implementation of C++ Concepts in Clang

Larisse Voufo, Marcin Zalewski, and Andrew LumsdaineOpen Systems Lab, Indiana University

Designing Concepts in C++

Concepts are the basis of generic programming

C++ does not have concepts language feature Generic programming uses templates

Concepts were proposed but not accepted for C++11

Insufficient implementation experience ConceptGCC was the only prototype available

ConceptClang Goals:

An Infrastructure for Implementing Concepts: In Clang Extensible and easily accessible Independent from any “Concepts” proposal.

“Texas”, “Indiana”, Other? Adaptable to any proposal.

An implementation based on pre-Frankfurt standard draft.

Clang: What:

LLVM Front-end for the C family of Languages

Why: Carefully designed coding guidelines. Modern C++ implementation technology

Highly structured code Easily understandable Modular—Library-based approach

License allows extension and experimentation

Templates: Example Template Definition:

Template Use:

traverse a range and accumulate its elements Need: an iterator, a binary operation

template<typename InputIterator, typename T, typename BinaryFunction>T accumulate(InputIterator first, InputIterator last, T init, BinaryFunction bin_op) { for (; first != last; ++first) init = bin_op(init, *first); return init;}

vector<int> v;int i = accumulate(v.begin(), v.end(), 0, plus<int>());

Templates: MechanismTemplate Definition:

Template Use:

Specialization:

Instantiation:

template<typename InputIterator, typename T, typename BinaryFunction>T accumulate(…) { …}

vector<int> v;int i = accumulate<vector<int>::iterator, int, plus<int> >(v.begin(), v.end(), 0, plus<int>());

int accumulate(vector<int>::iterator first, vector<int>::iterator last, int init, plus<int> bin_op);

int accumulate(vector<int>::iterator first, vector<int>::iterator last, int init, plus<int> bin_op) { …}

Type-CheckOnce!

Concepts in C++: Explicit Support Constrained Templates:

Concept Definitions: Concept Models

template<typename I, typename T, typename BinOp>requires (InputIterator<I>, BinaryFunction<BinOp>)

T accumulate(I first, I last, T init, BinOp bin_op) { for (; first != last; ++first) init = bin_op(init, *first); return init;}

concept InputIterator<typename T>{ typename value_type; T operator++(T);}

concept BinaryFunction<class BinOp>{…

}

concept_map InputIterator<vector<int>::iterator> { typedef int value_type; T operator++(T t) { … }}concept_map BinaryFunction<plus<int> >{

… }

Modeling Mechanisms may Differ…

Notion Of Models Prevails.

Constrained Template Definition:

Constrained Template Use:

vector<int> v;int i = accumulate<vector<int>::iterator, int, plus<int> >(v.begin(), v.end(), 0, plus<int>());

Constrained Templates: MechanismSpecialization:

Instantiation:

template<typename I, typename T, typename BinOp>requires(InputIterator<I>, BinaryFunction<BinOp>)T accumulate(…) { …}

int accumulate(vector<int>::iterator first, vector<int>::iterator last, int init, plus<int> bin_op);

int accumulate(vector<int>::iterator first, vector<int>::iterator last, int init, plus<int> bin_op) { …}

Type-check+

Constraint-checkOnce!

Templates: From Unconstrained to Constrained Poor error detection and

diagnosis: Point to internals of library Lengthy, hard-to-understand WORSE: Semantic errors

are not detected Language “tricks”:

too complex, error-prone, and limited

NEED: Separate type-checking!

Errors detected at source

Diagnoses indicate exact source Without leaking

implementation details Clang pretty-prints

Separate type-checking We know who to blame!

Templates: Problem – Example 1 Template Use:

Compiler error:

vector<void*> v;int i = accumulate(v.begin(), v.end(), 0, plus<int>());

Larisse-Voufos-MacBook-Pro:Experiments annlarysm$ g++ accumulate.cpp -o accumulate/usr/include/c++/4.2.1/bits/stl_numeric.h: In function ‘_Tp std::accumulate(_InputIterator, _InputIterator, _Tp, _BinaryOperation) [with _InputIterator = __gnu_cxx::__normal_iterator<void**, std::vector<void*, std::allocator<void*> > >, _Tp = int, _BinaryOperation = std::plus<int>]’:accumulate.cpp:23: instantiated from here/usr/include/c++/4.2.1/bits/stl_numeric.h:115: error: invalid conversion from ‘void*’ to ‘int’/usr/include/c++/4.2.1/bits/stl_numeric.h:115: error: initializing argument 2 of ‘_Tp std::plus<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = int]’

Incompatible

Binary Operator!

Larisse-Voufos-MacBook-Pro:Experiments annlarysm$ ~/llvm.test/llvm/Debug+Asserts/bin/clang++ accumulate.cpp -o accumulateaccumulate.cpp:40:10: error: no matching function for call to 'accumulate' int i = accumulate(v.begin(), v.end(), 0, plus<int>()); ^~~~~~~~~~accumulate.cpp:21:3: note: candidate template ignored: constraints check failure [with I = __gnu_cxx::__normal_iterator<void **, std::vector<void *, std::allocator<void *> > >, T = int, BinOp = std::plus<int>]T accumulate(I first, I last, T init, BinOp bin_op) { ^accumulate.cpp:20:24: note: Concept map requirement not met.requires (InputIterator<I>, BinaryFunction<BinOp>) ^accumulate.cpp:20:1: note: Constraints Check Failed: accumulate.requires (InputIterator<I>, BinaryFunction<BinOp>)^1 error generated.

Templates: Solution – Example 1

Templates: Problem – Example 2 Template Use:

Compiler error:

vector<int> v;sort(v.begin(), v.end(), not_equal_to<int>());

(None !?)Not Valid Ordering!

Larisse-Voufos-MacBook-Pro:Experiments annlarysm$ ~/llvm.test/llvm/Debug+Asserts/bin/clang++ accumulate.cpp -o accumulateaccumulate.cpp:44:2: error: no matching function for call to 'sort' sort(v.begin(), v.end(), not_equal_to<int>()); ^~~~accumulate.cpp:34:6: note: candidate template ignored: constraints check failure [with I = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, BinOp = std::not_equal_to<int>]void sort(I first, I last, BinOp comp) { ^accumulate.cpp:33:31: note: Concept map requirement not met.requires (RandomAccessIterator<I>, StrictWeakOrdering<BinOp>) ^accumulate.cpp:33:1: note: Constraints Check Failed: sort.requires (RandomAccessIterator<I>, StrictWeakOrdering<BinOp>)^1 error generated.

Templates: Solution – Example 2

Concepts (in C++): Essential Elements Concept Definitions

Concept refinements Associated declarations

Concept Modeling Concept models Implementations

Generic Algorithm Definition: Constrained templates Constrained environments

Generic Algorithm Use: Type-checking, extended Constraint-check

Gathers models for constraints Models for constraints

Stored with specialization

Implementation Considerations: General

Concept Definitions Scoping checks Lookup in refinements and

associated requirements

Concept Modeling Scoping checks Check: model vs. concept Lookup in concept

Generic Algorithm Definition: Check: constraints validity Check: body vs. constraints

Lookup in constraints

Generic Algorithm Use: Constraint-check

Gather models for constraints Store models for constraints

with Specialization – How?

Implementation Considerations: Across Different Proposals

Concept Definitions Non-dependence checks Lookup in refinements and

associated requirements

Concept Modeling Non-dependence checks Check: model vs. concept Lookup in concept

Generic Algorithm Definition: Check: constraints validity Check: body vs. constraints

Lookup in constraints

Generic Algorithm Use: Constraint-check

Gather models for constraints Store models for constraints

With specialization – How? Instantiation

Pseudo-signatures vs.

Valid Expressions?

Implicit vs. Explicit

Modeling?

Stronger vs. Weaker

Constraints?

How and Where?

Infrastructure Layer: No Difference!

ConceptClang Implementation Concept Definitions

All Declarations in ConceptDecl class

Name lookup, modified.

Concept Modeling All Declarations in

ConceptMapDecl class Check: model vs. concept

Concept map generation procedure

Name lookup, modified

Generic Algorithm Definition: Check: constraints validity

Concept map archetypes: represent constraints

Check: body vs. constraints Name Lookup, modified

Generic Algorithm Use: Constraint-check procedure

Returns models for constraints Store models for constraints

In structure for specialization. Instantiation

Rebuild declaration references

ConceptClang Implementation Concept Definitions

All Declarations in ConceptDecl class

Name Lookup, modified.

Concept Modeling All Declarations in

ConceptMapDecl class Check: model vs. concept

Concept map generation procedure

Name Lookup, modified

Generic Algorithm Definition: Check: constraints validity

Concept map archetypes: represent constraints

Check: body vs. constraints Name Lookup, modified

Generic Algorithm Use: Constraint-check procedure

Returns models for constraints Store models for constraints

In structure for specialization. Instantiation

Rebuild declaration references

ConceptClang Implementation:Modified Lookup Scope flags: control lookup

e.g. DeclScope parsing a context with multiple declarations

New scope flags: ConceptDefnScope ConceptMapScope RestrictedScope Restricted-

InstantiationScope

ConceptClang Implementation Concept Definitions

All Declarations in ConceptDecl class

Name Lookup, modified.

Concept Modeling All Declarations in

ConceptMapDecl class Check: model vs. concept

Concept map generation procedure

Name Lookup, modified

Generic Algorithm Definition: Check: constraints validity

Concept map archetypes: represent constraints

Check: body vs. constraints Name Lookup, modified

Generic Algorithm Use: Constraint-check procedure

Returns models for constraints Store models for constraints

In structure for specialization. Instantiation

Rebuild declaration references

Mutual Recursion

Constraints Check Procedure Constrained Template Definition:

Constrained Template Use:

Specialization:

Maps for Constraints:

Found or generated

template<typename I, typename T, typename BinOp>requires(InputIterator<I>, BinaryFunction<BinOp>)T accumulate(…) { …}

vector<int> v;int i = accumulate<vector<int>::iterator, int, plus<int> >(…);

int accumulate(vector<int>::iterator first, vector<int>::iterator last, int init, plus<int> bin_op);Constraints-Check

Type-Check

InputIterator<vector<int>:: iterator>,BinaryFunction<plus<int> >

Concept Map Generation:Satisfying Concept Refinements

Concept Definition:

Parsed Model Definition:

Final Model Implementation:

Refinement maps:

concept ForwardIterator <typename I> : InputIterator<I>, OutputIterator<I> { …}

concept_map ForwardIterator <vector<int>::iterator>{ …}

InputIterator<vector<int>::iterator>,OutputIterator<vector<int>::iterator>

Constraints-CheckType-Check

concept_map ForwardIterator<vector<int>::iterator>{ …}

Concept Map Template Generation:Satisfying Concept Refinements

Concept Definition:

Parsed Model Definition:

Final Model Implementation:

Refinement maps:

concept ForwardIterator <typename I> : InputIterator<I>, OutputIterator<I> { …}

template<typename Iter>requires (InputIterator<Iter>, OutputIterator<Iter>) concept_map ForwardIterator<Iter>{ …}

InputIterator<Iter>,OutputIterator<Iter>

Constraints-Check

Type-Check

concept_map ForwardIterator<vector<int>::iterator>{ …}

ConceptClang Implementation:References to Associated Declarations

Concept Definitions All Declarations in

ConceptDecl class Name Lookup, modified.

Concept Modeling All Declarations in

ConceptMapDecl class Check: model vs. concept

Concept map generation procedure

Name Lookup, modified

Generic Algorithm Definition: Check: constraints validity

Concept map archetypes: represent constraints

Check: body vs. constraints Name Lookup, modified

Generic Algorithm Use: Constraint-check procedure

Returns models for constraints Store models for constraints

In structure for specialization. Instantiation

Rebuild declaration references

Template Definition:

PARSING

ConceptClang Implementation:References to Associated Declarations

template<typename T,…>requires(C<T,…>,…)void func(T a,…) { … foo(…); …}

Template Specialization:

INSTANTIATION

void func(int a,…);

concept_map C<T,…> { … foo(…); …}

concept_map C<int,…> { … foo(…); …}

void func(int a,…) { … foo(…); …}

ConceptClang Implementation:References to Constrained Templates Similar to concept map templates generation

Constraints of calling context == template constraints Parsing + Rebuilding call expression.

Template Definitions:

Temporary Template Specialization:

PARSING

ConceptClang Implementation:References to Constrained Templates

template<typename T,…>requires(CD<T,…>,…)void func(T a,…) { … oth_func(a,…); …}

Template Specializations:

INSTANTIATION

void func(int a,…);

void func(int a,…) { … oth_func(a,…); …}

template<typename T,…>requires(C<T,…>,…)void oth_func(T a,…);

void oth_func(T a,…);

void oth_func(int a,…);

concept_map C<int,…>; …

concept_map CD<int,…>; …concept_map C<T,…>; …

ConceptClang Implementation Concept Definitions

All Declarations in ConceptDecl class

Name Lookup, modified.

Concept Modeling All Declarations in

ConceptMapDecl class Check: model vs. concept

Concept map generation procedure

Name Lookup, modified

Generic Algorithm Definition: Check: constraints validity

Concept map archetypes: represent constraints

Check: body vs. constraints Name Lookup, modified

Generic Algorithm Use: Constraint-check procedure

Returns models for constraints Store models for constraints

In structure for specialization. Instantiation

Rebuild declaration references

Reusability and automation Clang implementation is

reused: Type substitution Type deduction Parsing mechanism Scoping Unique identification

Essential Data StructuresConceptDecl

Concept Parameters

ConceptMapDeclTemplate Parameters

≠ 0, for concept map templates

TemplateDeclTemplate Parameters

DeclContext FoldingSetNode

Scope:DeclScope |

ConceptDeclScope | RestrictedScope

Scope:DeclScope |

ConceptMapScope | RestrictedScope

NamedDeclName

Decl …

ConceptClang Implementation Concept Definitions

All Declarations in ConceptDecl class

Name Lookup, modified.

Concept Modeling All Declarations in

ConceptMapDecl class Check: model vs. concept

Concept map generation procedure

Name Lookup, modified

Generic Algorithm Definition: Check: constraints validity

Concept map archetypes: represent constraints

Check: body vs. constraints Name Lookup, modified

Generic Algorithm Use: Constraint-check procedure

Returns models for constraints Store models for constraints

In structure for specialization. Instantiation

Rebuild declaration references

Concept-based overloading Function Overloading:

Partial order on functions Select most specialized function

Concept-based Overloading: Constraints resolve ambiguities Select most constrained as well

Question:Given functions A and B, when: A is more constrained than B, and B is more specialized than A Select which one?

//#1template <class FI> FI min_element(FI first, FI last);

//#2template <class T>T* min_element(T* first, T* last);

//Instantiation chooses #2int *p1, *p2;int* p = min_element(p1, p2);

//#1template <class FI> FI min_element(FI first, FI last);

//#2template <class FI>requires ForwardIterator<FI> FI min_element(FI first, FI last);

//#3template <class RI>requires RandomAccessIterator<RI> RI min_element(RI first, RI last);

concept_map ForwardIterator<int*>;concept_map RandomAccessIterator<int*>;

//Instantiation chooses #3int *p1, *p2;int* p = min_element(p1, p2);

//#Btemplate <class T>T* min_element(T* first, T* last);

//#Atemplate <class FI>requires ForwardIterator<FI> FI min_element(FI first, FI last);

concept_map ForwardIterator<int*>;

//Instantiation chooses ???int *p1, *p2;int* p = min_element(p1, p2);

Concept-based overloading Question:

Given functions A and B, when: A is more constrained than B, and B is more specialized than A Select which one?

Answer: Pre-Frankfurt C++: B ConceptClang: A Right answer? Open question!

//#Btemplate <class T>T* min_element(T* first, T* last);

//#Atemplate <class FI>requires ForwardIterator<FI> FI min_element(FI first, FI last);

concept_map ForwardIterator<int*>;

//Instantiation chooses ???int *p1, *p2;int* p = min_element(p1, p2);

Practical Example: Mini-BGL

template <typename G, typename C, typename Vis>requires (VertexListGraph<G>, IncidenceGraph<G>, ReadWriteMap<C>, SameType<ReadMap<C>::key, Graph<G>::vertex>,

Color<ReadMap<C>::value>, BFSVisitor<Vis, G>) void breadth_first_search(const G& g, vertex s, C c, Vis vis) {

pair<vertex_iter, vertex_iter> iter_pair = vertices(g);for(vertex_iter iter = iter_pair.first,

iter_end = iter_pair.second; iter != iter_end; ++iter) {

vertex u = *iter;initialize_vertex(vis, u, g);set(c, u, white());

}std::queue<int> Q;graph_search(g, s, vis, c, Q);

}

template <typename G, typename C, typename Vis, typename QType>requires (VertexListGraph<G>, IncidenceGraph<G>, ReadWriteMap<C>, SameType<ReadMap<C>::key, Graph<G>::vertex>,

Color<ReadMap<C>::value>, Visitor<Vis, G>, Bag<Qtype>) void graph_search(const G& g, vertex s, Vis vis, C c, Qtype& Q);

Thank You! Questions?

http://www.generic-programming.org/software/ConceptClang/

template <typename G, typename C, typename Vis>requires (VertexListGraph<G>, IncidenceGraph<G>, ReadWriteMap<C>, SameType<ReadMap<C>::key, Graph<G>::vertex>,

Color<ReadMap<C>::value>, BFSVisitor<Vis, G>) void breadth_first_search(const G& g, vertex s, C c, Vis vis) {

pair<vertex_iter, vertex_iter> iter_pair = vertices(g);for(vertex_iter iter = iter_pair.first,

iter_end = iter_pair.second; iter != iter_end; ++iter) {

vertex u = *iter;initialize_vertex(vis, u, g);set(c, u, white());

}std::queue<int> Q;graph_search(g, s, vis, c, Q);

}