4. What is Ts and vs?
• Ts is an alias for a list of types
• vs is an alias for a list of values
typedef Ts MyList; // error!
Ts var;// error!
auto copy = vs;// error!
Quickoffice Proprietary and Confidential - Not for Disclosure 4
5. Parameters Packs Usage
• Get pack size
size_t items = sizeof...(Ts); // or vs
• Expand back
template<typename... Ts>
voidfoo(const Ts&... Vs) {
goo(1, std::forward<Ts>(vs)..., 42);
}
Quickoffice Proprietary and Confidential - Not for Disclosure 5
7. Where to use?
• Initializer lists
int a[] = { vs... };
• Base class specifier
template<typename... Ts>
struct A : B<Ts>...
{
};
• Class members initializer lists
template<typename... Us>
A(Us... vs) : B<Ts>(vs)... {}
Quickoffice Proprietary and Confidential - Not for Disclosure 7
8. Where to use?
• Template arguments lists
std::map<Ts...>foo;
• Exception specifications
• Capture lists
template<class... Ts>
voidfoo(Ts... vs) {
autolamda = [&vs...] { returngoo(vs...); }
lamda();
}
Quickoffice Proprietary and Confidential - Not for Disclosure 8
10. Where is used?
• std::make_shared
template<class T, class... Ts>
shared_ptr<T>make_shared(Ts&&... vs);
• std::vector::emplace_back
template<class... Args>
voidemplace_back(Args&&... args);
Quickoffice Proprietary and Confidential - Not for Disclosure 10
11. Typesafeprintf
• Stock printf:
– Fast
– Thread-safe
– Convenient
– Ubiquitously known
– Utterly unsafe
• Goal: add verification of the provided parameters
Quickoffice Proprietary and Confidential - Not for Disclosure 11
19. Why?
intw = 0;
for (inti = 0; i<3; i++)
w += w * 2;
$ gcc -fsyntax-only test.c
test.c:2: error: expected identifier or ‘(’ before ‘for’
test.c:2: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘<’ token
test.c:2: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘++’
token
Quickoffice Proprietary and Confidential - Not for Disclosure 19
20. Why?
“... is there a reason for not making the
[GCC] front ends dynamic libraries
which could be linked by any program
that wants to parse source code?”
“One of our main goals for GCC is to prevent
any parts of it from being used together with
non-free software. Thus, we have deliberately
avoided many things that might possibly have
the effect of facilitating such usage...”
- Richard Stallman
Quickoffice Proprietary and Confidential - Not for Disclosure 20
21. Why?
#define FOO 0
intfoo() {
intx;
// ...
x = x + FOO;
// ...
returnx;
}
#define FOO 0
intfoo() {
intx;
// ...
x = x;
// ...
returnx;
}
Quickoffice Proprietary and Confidential - Not for Disclosure 21
23. Diagnostics
$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:1:38:error:'arr' declared as an array with a negative size
template <int N>struct S1 { intarr[N - 5]; };
^~~~~
test.cpp:2:49: note: in instantiation of template class 'S1<4>' requested here
template <typename T>struct S2 { S1<sizeof(T)> s1; };
^
test.cpp:3:45: note: in instantiation of template class 'S2<int>' requested here
template <typename T> void foo(Tx) { S2<T> s2; }
^
test.cpp:4:15: note: in instantiation of function template specialization 'foo<int>'
requested here
void test() { foo(42); }
^
1 error generated.
Quickoffice Proprietary and Confidential - Not for Disclosure 23
24. Diagnostics
#define M1(x, y, z) y();
#define M2(x, y, z) M1(x, y, z)
void test() {
M2(a, b, c)
;}
Quickoffice Proprietary and Confidential - Not for Disclosure 24
25. Diagnostics
$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:4:11: error: use of undeclared identifier 'b’
M2(a, b, c);
^
test.cpp:2:27: note: expanded from macro 'M2'
#define M2(x, y, z) M1(x, y, z)
^
test.cpp:1:21: note: expanded from macro 'M1'
#define M1(x, y, z) y();
^
1 error generated.
$ g++ -fsyntax-only test.cpp
test.cpp: In function ‘void test()’:
test.cpp:4: error: ‘b’ was not declared in this scope
Quickoffice Proprietary and Confidential - Not for Disclosure 25
27. Diagnostics
% clang++ -std=c++11 -fsyntax-only typo1.cpp
typo1.cpp:4:19: error:initializer 'basetype' does not name a non-static
data member or base class; did you mean the base class 'BaseType’?
DerivedType() : basetype() {}
^~~~~~~~
BaseType
typo1.cpp:2:22: note: base class 'BaseType' specified here
structDerivedType : public BaseType {
^~~~~~~~~~~~~~~
1 error generated.
Quickoffice Proprietary and Confidential - Not for Disclosure 27
29. Diagnostics
$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:3:13:error:no member named 'st_blocksize' in 'stat'; did you
mean 'st_blksize'?
return P->st_blocksize*2;
^~~~~~~~~~~~
st_blksize
/usr/include/sys/stat.h:225:13: note: 'st_blksize' declared here
struct stat __DARWIN_STRUCT_STAT64;
^
/usr/include/sys/stat.h:212:12: note: expanded from macro
'__DARWIN_STRUCT_STAT64'
blksize_tst_blksize; /*... */
^
1 error generated.
Quickoffice Proprietary and Confidential - Not for Disclosure 29
30. Diagnostics
template<class T, class U>struct S {};
template<typename... Ts>voidf(Ts...);
template<typename... Ts>struct X {
template<typename... Us>voidg() {
f(S<Ts, Us>()...);
}
};
voidtest(X<int, float>x)
{
x.g<int, float, double>();
}
Quickoffice Proprietary and Confidential - Not for Disclosure 30
31. Diagnostics
$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:8:22: error: pack expansion contains parameter packs 'Ts' and
'Us' that have different lengths (2 vs. 3)
f(S<Ts, Us>()...);
~~ ~~ ^
test.cpp:14:7: note: in instantiation of function template specialization 'X<int,
float>::g<int, float, double>' requested here
x.g<int, float, double>();
^
1 error generated.
Quickoffice Proprietary and Confidential - Not for Disclosure 31
32. Diagnostics
#include <memory.h>
struct S { int a, b, c; float vec[16]; };
voidtest(S *s)
{
// ...
memset(s, 0, sizeof(s));
// ...
}
Quickoffice Proprietary and Confidential - Not for Disclosure 32
33. Diagnostics
$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:5:25: warning: argument to 'sizeof' in 'memset' call is the same
expression as the destination; did you mean to dereference it? [-
Wsizeof-pointer-memaccess]
memset(s, 0, sizeof(s));
~ ^
1 warning generated.
Quickoffice Proprietary and Confidential - Not for Disclosure 33
35. Diagnostics
$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:4:12: warning: array index of '42' indexes past the end of an array
(that contains 42 elements) [-Warray-bounds]
return arr[42];
^ ~~
test.cpp:2:5: note: array 'arr' declared here
int arr[42];
^
1 warning generated.
Quickoffice Proprietary and Confidential - Not for Disclosure 35
37. Diagnostics
$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:2:23: warning: signed shift result (0x200000000) requires 35 bits
to represent, but 'int' only has 32 bits [-Wshift-overflow]
DiskCacheSize = 8 << 30; // 8 Gigs
~ ^ ~~
1 warning generated.
Quickoffice Proprietary and Confidential - Not for Disclosure 37
39. Diagnostics
$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:2:19: warning: '&&' within '||' [-Wlogical-op-parentheses]
if (b || x<y&&x> 0) {
~~ ~~~~~~^~~~~~~~
test.cpp:2:19: note: place parentheses around the '&&' expression to silence
this warning
if (b || x<y&&x> 0) {
^
( )
1 warning generated.
Quickoffice Proprietary and Confidential - Not for Disclosure 39
40. Diagnostics
constexprintarr_size = 42;
constexprint N = 44;
voidf(int);int test()
{
intarr[arr_size];
// ...
f(arr[N]);
// ...
if (N <arr_size) returnarr[N];
return0;
}
Quickoffice Proprietary and Confidential - Not for Disclosure 40
41. Diagnostics
$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:7:7: warning: array index of '44' indexes past the end of an array
(that contains 42 elements) [-Warray-bounds]
f(arr[N]);
^ ~
test.cpp:5:5:note: array 'arr' declared here
intarr[arr_size];
^
1 warning generated.
Quickoffice Proprietary and Confidential - Not for Disclosure 41
42. Static Analysis
structmutex {
void lock();
void unlock();
};
mutexm;
intx;
boolfoo();
bool bar();
void test() {
m.lock();
while (foo()) {
m.unlock();
if (bar()) {
if (x<42&&foo()){
continue;
}
}
m.lock();
}
}
Quickoffice Proprietary and Confidential - Not for Disclosure 42
43. Static Analysis
struct [[ts::lockable]] mutex {
void lock() [[ts::exclusive_lock_function]];
void unlock() [[ts::unlock_function]];
};
mutexm;
intx [[ts::guarded_by(m)]];
boolfoo() [[ts::exclusive_locks_required(m)]];
bool bar();
void test() {
m.lock();
while (foo()) {
m.unlock();
if (bar()) {
if (x<42&&foo()){
continue;
}
}
m.lock();
}
}
Quickoffice Proprietary and Confidential - Not for Disclosure 43
44. Static Analysis
struct __attribute__((lockable)) mutex {
void lock() __attribute__((exclusive_lock_function));
void unlock() __attribute__((unlock_function));
};
mutexm;
intx__attribute__((guarded_by(m)));
boolfoo() __attribute__((exclusive_locks_required(m)));
bool bar();
void test() {
m.lock();
while (foo()) {
m.unlock();
if (bar()) {
if (x<42&&foo()){
continue;
}
}
m.lock();
}
}
Quickoffice Proprietary and Confidential - Not for Disclosure 44
45. Diagnostics
$ clang++ -std=c++11 -fsyntax-only -Wthread-safety test.cpp
test.cpp:11:5: warning: expecting mutex 'm' to be locked at start of each
loop [-Wthread-safety]
m.lock();
^
test.cpp:11:5: warning:mutex 'm' is still locked at the end of function [-
Wthread-safety]
test.cpp:15:17: warning: reading variable 'x' requires locking 'm' [-
Wthread-safety]
if (x< 42 &&foo()) {
^
test.cpp:19:9: warning:mutex 'm' is still locked at the end of its scope [-
Wthread-safety]
m.lock();
^
4 warnings generated.
Quickoffice Proprietary and Confidential - Not for Disclosure 45
46. Current Status
• Platforms:
+ Linux
+ Mac OS X
– Windows
• C++11 features:
+ Almost all features implemented in v2.9+/SVN
– Missing features:
• Generalized attributes
• Inheriting constructors
• Concurrency
Quickoffice Proprietary and Confidential - Not for Disclosure 46
47. Brief architecture overview
• GCC compatible
• Library based architecture
– libsupport, libsystem, libbasic, libast, liblex, libparse, libsema,
libcodegen, librewrite, libanalysis, libindex
• One kind of as AST for C++/C and Objective-C
• Visitor interface ASTConsumer for Front-end actions
Quickoffice Proprietary and Confidential - Not for Disclosure 47
48. Sample ASTConsumer
classPrintFunctionsConsumer : publicASTConsumer
{
public:
virtualvoidHandleTopLevelDecl(DeclGroupRef DG)
{
for (DeclGroupRef::iterator it = DG.begin();
it != DG.end();
++it)
{
constDecl* D = *it;
if (constNamedDecl* ND = dyn_cast<NamedDecl>(D))
llvm::errs() << ” topleveldecl : ” ”
<< ND->getNameAsString()
<< ” ” n ”;
}
}
};
Quickoffice Proprietary and Confidential - Not for Disclosure 48
49. Thirdparty tools
http://code.google.com/p/include-what-you-use/
"Include what you use" means this: for every symbol (type,
function variable, or macro) that you use in foo.cc, either foo.cc
or foo.h should #include a .h file that exports the declaration of
that symbol. The include-what-you-use tool is a program that
can be built with the clang libraries in order to analyze
#includes of source files to find include-what-you-use
violations, and suggest fixes for them.
Quickoffice Proprietary and Confidential - Not for Disclosure 49