C++ Support in Clang
This page tracks the status of C++ support in Clang.
Currently most of the C++ features are missing; here you can find features that are at least partially supported in Clang.
The following table is used to help track our implementation progress toward implementing the complete C++03 standard. We use a simple, somewhat arbitrary color-coding scheme to describe the relative completeness of features by section:
Not started/not evaluated | Not Applicable | Broken | Some examples work | Many examples work | Nearly everything works | Complete! |
---|---|---|---|---|---|---|
N/A | ✓ |
A feature is "complete" when the appropriate Clang component (Parse, AST, Sema, CodeGen) implements the behavior described in all of the paragraphs in the relevant C++ standard. Note that many C++ features are actually described in several different sections within the standard. The major components are:
- Parse
- Clang is able to parse the grammar of this feature (or the grammar described by this section), but does not necessarily do anything with the parsed result. Use Clang's
-fsyntax-only
option to parse C++ programs. - AST
- Clang builds an abstract syntax tree (AST) for the feature, but does not necessarily perform any type-checking. Use Clang's
-ast-print
option to print the resulting ASTs. - Sema
- Clang parses and type-checks this feature and provides a well-formed AST annotated with types. Use Clang's
-fsyntax-only
to type-check code. - CodeGen
- Clang parses, type-checks, and generates code for this feature, allowing one to compile and execute programs.
Updates to this table are welcome! Since Clang already supports much of C, and therefore much C++, many of the currently-white cells could be filled in. If you wish to do so, please compare Clang's implementation against the C++ standard and provide a patch that updates the table accordingly. Tests for the various features are also welcome!
Section | Parse | AST | Sema | CodeGen | Notes |
---|---|---|---|---|---|
2 [lex] | ✓ | N/A | N/A | N/A | |
2.1 [lex.phases] | N/A | N/A | N/A | Extended characters aren't handled. | |
2.2 [lex.charset] | N/A | N/A | N/A | No support for extended characters. | |
2.3 [lex.trigraph] | ✓ | N/A | N/A | N/A | |
2.4 [lex.pptoken] | ✓ | N/A | N/A | N/A | |
2.5 [lex.digraph] | ✓ | N/A | N/A | N/A | |
2.6 [lex.token] | ✓ | N/A | N/A | N/A | |
2.7 [lex.comment] | N/A | N/A | NDR "form feed or vtab in comment" is not diagnosed. No AST representation of comments. | ||
2.8 [lex.header] | ✓ | N/A | N/A | N/A | |
2.9 [lex.ppnumber] | ✓ | N/A | N/A | N/A | |
2.10 [lex.name] | N/A | N/A | N/A | No support for extended characters | |
2.11 [lex.key] | ✓ | N/A | N/A | N/A | |
2.12 [lex.operators] | ✓ | N/A | N/A | N/A | |
2.13 [lex.literal] | ✓ | N/A | N/A | N/A | |
2.13.1 [lex.icon] | ✓ | N/A | N/A | N/A | |
2.13.2 [lex.ccon] | N/A | N/A | N/A | Poor support for extended characters | |
2.13.3 [lex.fcon] | ✓ | N/A | N/A | N/A | |
2.13.4 [lex.string] | N/A | N/A | N/A | Poor support for extended characters | |
2.13.5 [lex.bool] | ✓ | N/A | N/A | N/A | |
3 [basic] | N/A | N/A | N/A | N/A | |
3.1 [basic.def] | N/A | ||||
3.2 [basic.def.odr] | |||||
3.3 [basic.scope] | N/A | N/A | ✓ | N/A | |
3.3.1 [basic.scope.pdecl] | N/A | N/A | N/A | See PR3184 | |
3.3.2 [basic.scope.local] | N/A | N/A | N/A | try-catch not implemented | |
3.3.3 [basic.scope.proto] | N/A | N/A | ✓ | N/A | |
3.3.4 [basic.funscope] | N/A | N/A | ✓ | N/A | |
3.3.5 [basic.scope.namespace] | |||||
3.3.6 [basic.scope.class] | |||||
3.3.7 [basic.scope.hiding] | N/A | N/A | ✓ | N/A | |
3.4 [basic.lookup] | N/A | N/A | ✓ | N/A | |
3.4.1 [basic.lookup.unqual] | N/A | N/A | N/A | Many cases beyond simple global and function-local lookup don't work | |
3.4.2 [basic.lookup.argdep] | N/A | N/A | Missing support for templates, friend functions. | ||
3.4.3 [basic.lookup.qual] | N/A | N/A | N/A | ||
3.4.3.1 [class.qual] | N/A | N/A | N/A | ||
3.4.3.2 [namespace.qual] | N/A | N/A | N/A | ||
3.4.4 [basic.lookup.elab] | |||||
3.4.5 [basic.lookup.classref] | |||||
3.4.6 [basic.lookup.udir] | |||||
3.5 [basic.link] | |||||
3.6 [basic.start] | |||||
3.6.1 [basic.start.main] | |||||
3.6.2 [basic.start.init] | |||||
3.6.3 [basic.start.term] | |||||
3.7 [basic.stc] | |||||
3.7.1 [basic.stc.static] | |||||
3.7.2 [basic.stc.auto] | |||||
3.7.3 [basic.stc.dynamic] | |||||
3.7.3.1 [basic.stc.dynamic.allocation] | |||||
3.7.3.2 [basic.stc.dynamic.deallocation] | |||||
3.7.4 [basic.stc.inherit] | |||||
3.8 [basic.life] | |||||
3.9 [basic.types] | |||||
3.9.1 [basic.fundamental] | |||||
3.9.2 [basic.compound] | |||||
3.9.3 [basic.type.qualifier] | |||||
3.10 [basic.lval] | |||||
4 [conv] | ✓ | ✓ | ✓ | ||
4.1 [conv.lval] | ✓ | ✓ | |||
4.2 [conv.array] | ✓ | ✓ | ✓ | ||
4.3 [conv.func] | ✓ | ✓ | |||
4.4 [conv.qual] | ✓ | ✓ | ✓ | ||
4.5 [conv.prom] | ✓ | ✓ | ✓ | ||
4.6 [conv.fpprom] | ✓ | ✓ | ✓ | ||
4.7 [conv.integral] | ✓ | ✓ | ✓ | ||
4.8 [conv.double] | ✓ | ✓ | ✓ | ||
4.9 [conv.fpint] | ✓ | ✓ | ✓ | ||
4.10 [conv.ptr] | ✓ | ✓ | ✓ | ||
4.11 [conv.mem] | ✓ | ✓ | ✓ | ||
4.12 [conv.bool] | ✓ | ✓ | ✓ | ||
5 [expr] | N/A | N/A | ✓ | ||
5.1 [expr.prim] | template-ids are not supported, name lookup is not complete | ||||
5.2 [expr.post] | |||||
5.2.1 [expr.sub] | ✓ | ✓ | ✓ | ||
5.2.2 [expr.call] | ✓ | ✓ | Argument-dependent lookup is unsupported | ||
5.2.3 [expr.type.conv] | ✓ | ✓ | Only between non-class types | ||
5.2.4 [expr.pseudo] | |||||
5.2.5 [expr.ref] | ✓ | Cannot look up operator names, qualified-ids, or names in base classes | |||
5.2.6 [expr.post.incr] | ✓ | ✓ | ✓ | ||
5.2.7 [expr.dynamic.cast] | ✓ | ✓ | ✓ | ||
5.2.8 [expr.typeid] | ✓ | ✓ | ✓ | ||
5.2.9 [expr.static.cast] | ✓ | ✓ | Some custom conversions don't work. | ||
5.2.10 [expr.reinterpret.cast] | ✓ | ✓ | ✓ | ||
5.2.11 [expr.const.cast] | ✓ | ✓ | ✓ | ||
5.3 [expr.unary] | |||||
5.3.1 [expr.unary.op] | |||||
5.3.1p1 Unary * | ✓ | ✓ | ✓ | ||
5.3.1p2-5 Unary & | ✓ | ✓ | ✓ | ||
5.3.1p6 Unary + | ✓ | ✓ | ✓ | ||
5.3.1p7 Unary - | ✓ | ✓ | ✓ | ||
5.3.1p8 Unary ! | ✓ | ✓ | ✓ | ||
5.3.1p9 Unary ~ | ✓ | ✓ | ✓ | ||
5.3.2 [expr.pre.incr] | ✓ | ✓ | ✓ | ||
5.3.3 [expr.sizeof] | ✓ | ✓ | ✓ | ||
5.3.4 [expr.new] | ✓ | ✓ | operator delete is not looked up, initialization not quite correct | ||
5.3.5 [expr.delete] | ✓ | ✓ | ✓ | ||
5.4 [expr.cast] | ✓ | ✓ | Too lenient, and may not always have correct semantics | ||
5.5 [expr.mptr.oper] | ✓ | Dereferenced member function pointers have the wrong type. | |||
5.6 [expr.mul] | ✓ | ✓ | ✓ | ||
5.7 [expr.add] | ✓ | ✓ | ✓ | ||
5.8 [expr.shift] | ✓ | ✓ | ✓ | ||
5.9 [expr.rel] | ✓ | ✓ | ✓ | ||
5.10 [expr.eq] | ✓ | ✓ | ✓ | ||
5.11 [expr.bit.and] | ✓ | ✓ | ✓ | ||
5.12 [expr.xor] | ✓ | ✓ | ✓ | ||
5.13 [expr.or] | ✓ | ✓ | ✓ | ||
5.14 [expr.log.and] | ✓ | ✓ | ✓ | ||
5.15 [expr.log.or] | ✓ | ✓ | ✓ | ||
5.16 [expr.cond] | ✓ | ✓ | throw expressions not supported, type unification rules are based on C only | ||
5.17 [expr.ass] | ✓ | ✓ | ✓ | ||
5.18 [expr.comma] | ✓ | ✓ | ✓ | ||
5.19 [expr.const] | ✓ | ✓ | Uses C semantics | ||
6 [stmt.stmt] | ✓ | ✓ | ✓ | ||
6.1 [stmt.label] | ✓ | ✓ | ✓ | ||
6.2 [stmt.expr] | ✓ | ✓ | ✓ | ||
6.3 [stmt.block] | ✓ | ✓ | ✓ | ||
6.4 [stmt.select] | ✓ | ✓ | Conversion of declarations to required types not really supported. | ||
6.4.1 [stmt.if] | ✓ | ✓ | ✓ | ||
6.4.2 [stmt.switch] | ✓ | ✓ | ✓ | ||
6.5 [stmt.iter] | ✓ | ✓ | Conversion of declarations to required types not really supported. | ||
6.5.1 [stmt.while] | ✓ | ✓ | ✓ | ||
6.5.2 [stmt.do] | ✓ | ✓ | ✓ | ||
6.5.3 [stmt.for] | ✓ | ✓ | ✓ | ||
6.6 [stmt.jump] | ✓ | ✓ | ✓ | ||
6.6.1 [stmt.break] | ✓ | ✓ | ✓ | ||
6.6.2 [stmt.cont] | ✓ | ✓ | ✓ | ||
6.6.3 [stmt.return] | ✓ | ✓ | ✓ | ||
6.6.4 [stmt.goto] | ✓ | ✓ | ✓ | ||
6.7 [stmt.dcl] | ✓ | ✓ | Skipping of initialization is not flagged. Existence and accessibility of destructors is not tested for. | ||
6.8 [stmt.ambig] | ✓ | ✓ | ✓ | ||
7 [dcl.dcl] | |||||
7.1 [dcl.spec] | No support for friend declarations. | ||||
7.1.1 [dcl.stc] | ✓ | Linkage merging has some errors. | |||
7.1.2 [dcl.fct.spec] | ✓ | ✓ | ✓ | ||
7.1.3 [dcl.typedef] | ✓ | ✓ | ✓ | Typedefs of anonymous tag types do not use the name of the typedef for linkage purposes. | |
7.1.4 [dcl.friend] | |||||
7.1.5 [dcl.type] | ✓ | ✓ | ✓ | ||
7.1.5.1 [dcl.type.cv] | ✓ | ✓ | ✓ | ||
7.1.5.2 [dcl.type.simple] | Cannot parse template IDs. | ||||
7.1.5.3 [dcl.type.elab] | Cannot parse template IDs. | ||||
7.2 [dcl.enum] | ✓ | ✓ | ✓ | ||
7.3 [basic.namespace] | ✓ | ✓ | ✓ | ||
7.3.1 [namespace.def] | Cannot parse namespace aliases. | ||||
7.3.1.1 [namespace.unnamed] | ✓ | ✓ | Unnamed namespace members cannot be looked up. | ||
7.3.1.2 [namespace.memdef] | ✓ | ✓ | The friend stuff is not supported. | ||
7.3.2 [namespace.alias] | |||||
7.3.3 [namespace.udecl] | |||||
7.3.4[namespace.udir] | ✓ | ✓ | Example in p4 fails. | ||
7.4 [dcl.asm] | ✓ | ✓ | ✓ | ||
7.5 [dcl.link] | ✓ | ||||
8 [dcl.decl] | |||||
8.1 [dcl.name] | |||||
8.2 [dcl.ambig.res] | |||||
8.3 [dcl.meaning] | |||||
8.3.1 [dcl.ptr] | |||||
8.3.2 [dcl.ref] | |||||
8.3.3 [dcl.mptr] | |||||
8.3.4 [dcl.array] | |||||
8.3.5 [dcl.fct] | |||||
8.3.6 [dcl.fct.default] | Missing default arguments for templates. | ||||
8.4 [dcl.fct.def] | |||||
8.5 [dcl.init] | |||||
8.5.1[dcl.init.aggr] | No CodeGen for initializing non-aggregates or dynamic initialization. | ||||
8.5.2 [dcl.init.string] | |||||
8.5.3 [dcl.init.ref] | |||||
9 [class] | |||||
9.1 [class.name] | ✓ | ||||
9.2 [class.mem] | No parser support for using declarations, or templates. | ||||
9.3 [class.mfct] | ✓ | ||||
9.3.1 [class.mfct.non-static] | ✓ | ||||
9.3.2 [class.this] | ✓ | ||||
9.4 [class.static] | ✓ | ||||
9.4.1 [class.static.mfct] | ✓ | ||||
9.4.2 [class.static.data] | ✓ | ||||
9.5 [class.union] | ✓ | ✓ | Semantic analysis does not yet check all of the requirements placed on the members of unions. | ||
9.6 [class.bit] | ✓ | ||||
9.7 [class.nest] | ✓ | ||||
9.8 [class.local] | ✓ | ||||
9.9 [class.nested.type] | ✓ | ||||
10 [class.derived] | |||||
10.1 [class.mi] | |||||
10.2 [class.member.lookup] | |||||
10.3 [class.virtual] | |||||
10.4 [class.abstract] | |||||
11 [class.access] | |||||
11.1 [class.access.spec] | |||||
11.2 [class.access.base] | |||||
11.3 [class.access.dcl] | |||||
11.4 [class.friend] | |||||
11.5 [class.protected] | |||||
11.6 [class.access.virt] | |||||
11.7 [class.paths] | |||||
11.8 [class.access.nest] | |||||
12 [special] | |||||
12.1 [class.ctor] | |||||
12.2 [class.temporary] | |||||
12.3 [class.conv] | |||||
12.3.1 [class.conv.ctor] | |||||
12.3.2 [class.conv.fct] | Conversion functions can be declared and defined, but aren't used for anything. | ||||
12.4 [class.dtor] | Most of the semantics of destructors are unimplemented. | ||||
12.5 [class.free] | |||||
12.6 [class.init] | |||||
12.6.1 [class.expl.init] | |||||
12.6.2 [class.base.init] | No actual direct initialization; implicit initialization not checked. | ||||
12.7 [class.cdtor] | |||||
12.8 [class.copy] | |||||
13 [over] | |||||
13.1 [over.load] | ✓ | Missing name mangling. | |||
13.2 [over.dcl] | ✓ | ||||
13.3 [over.match] | ✓ | ||||
13.3.1 [over.match.funcs] | ✓ | ||||
13.3.1.1 [over.match.call] | ✓ | ||||
13.3.1.1.1 [over.call.func] | ✓ | ||||
13.3.1.1.2 [over.call.object] | ✓ | Missing AST representation for the implicit conversion to a function reference/pointer | |||
13.3.1.2 [over.match.oper] | ✓ | ||||
13.3.1.3 [over.match.ctor] | ✓ | ||||
13.3.1.4 [over.match.copy] | ✓ | ||||
13.3.1.5 [over.match.conv] | ✓ | ||||
13.3.1.6 [over.match.ref] | ✓ | ||||
13.3.2 [over.match.viable] | ✓ | ||||
13.3.3 [over.match.best] | ✓ | ||||
13.3.3.1 [over.best.ics] | ✓ | ||||
13.3.3.1.1 [over.ics.scs] | ✓ | ||||
13.3.3.1.2 [over.ics.user] | ✓ | ||||
13.3.3.1.3 [over.ics.ellipsis] | ✓ | ||||
13.3.3.1.4 [over.ics.ref] | ✓ | ||||
13.3.3.2 [over.ics.rank] | ✓ | ||||
13.4 [over.over] | Error messages need some work. Without templates or using declarations, we don't have any ambiguities, so the semantic analysis is incomplete. | ||||
13.5 [over.oper] | Some overloaded operators can only be called with function syntax, e.g., operator[](x) . |
||||
13.5.1 [over.unary] | N/A | ||||
13.5.2 [over.binary] | N/A | ||||
13.5.3 [over.ass] | N/A | ||||
13.5.4 [over.call] | N/A | ||||
13.5.5 [over.sub] | N/A | ||||
13.5.6 [over.ref] | N/A | ||||
13.5.7 [over.inc] | N/A | ||||
13.6 [over.built] | N/A | Missing pointer-to-member versions (p11, p16) and support for the ternary operator (p24, p25). | |||
14 [temp] | |||||
14.1 [temp.param] | |||||
14.2 [temp.names] | |||||
14.3 [temp.arg] | |||||
14.3.1 [temp.arg.type] | |||||
14.3.2 [temp.arg.nontype] | |||||
14.3.3 [temp.arg.template] | |||||
14.4 [temp.type] | |||||
14.5 [temp.decls] | |||||
14.5.1 [temp.class] | |||||
14.5.1.1 [temp.mem.func] | |||||
14.5.1.2 [temp.mem.class] | |||||
14.5.1.3 [temp.static] | |||||
14.5.2 [temp.mem] | |||||
14.5.3 [temp.friend] | |||||
14.5.4 [temp.class.spec] | |||||
14.5.5.1 [temp.class.spec.match] | |||||
14.5.5.2 [temp.class.order] | |||||
14.5.5.3 [temp.class.spec.mfunc] | |||||
14.5.5 [temp.fct] | |||||
14.5.5.1 [temp.over.link] | |||||
14.5.5.2 [temp.func.order] | |||||
14.6 [temp.res] | |||||
14.6.1 [temp.local] | |||||
14.6.2 [temp.dep] | |||||
14.6.2.1 [temp.dep.type] | |||||
14.6.2.2 [temp.dep.expr] | |||||
14.6.2.3 [temp.dep.constexpr] | |||||
14.6.2.4 [temp.dep.temp] | |||||
14.6.3 [temp.nondep] | |||||
14.6.4 [temp.dep.res] | |||||
14.6.4.1 [temp.point] | |||||
14.6.4.2 [temp.dep.candidate] | |||||
14.6.5 [temp.inject] | |||||
14.7 [temp.spec] | |||||
14.7.1 [temp.inst] | |||||
14.7.2 [temp.explicit] | |||||
14.7.3 [temp.expl.spec] | |||||
14.8 [temp.fct.spec] | |||||
14.8.1 [temp.arg.explicit] | |||||
14.8.2 [temp.deduct] | |||||
14.8.2.1 [temp.deduct.call] | |||||
14.8.2.2 [temp.deduct.funcaddr] | |||||
14.8.2.3 [temp.deduct.conv] | |||||
14.8.2.4 [temp.deduct.type] | |||||
14.8.3 [temp.over] | |||||
15 [except] | |||||
15.1 [except.throw] | |||||
15.2 [except.ctor] | |||||
15.3 [except.handle] | |||||
15.4 [except.spec] | |||||
15.5 [except.special] | |||||
15.5.1 [except.terminate] | |||||
15.5.2 [except.unexpected] | |||||
15.5.3 [except.uncaught] | |||||
15.6 [except.access] | |||||
16 [cpp] | |||||
16.1 [cpp.cond] | |||||
16.2 [cpp.include] | |||||
16.3 [cpp.replace] | |||||
16.3.1 [cpp.subst] | |||||
16.3.2 [cpp.stringize] | |||||
16.3.3 [cpp.concat] | |||||
16.3.4 [cpp.rescan] | |||||
16.3.5 [cpp.scope] | |||||
16.4 [cpp.line] | |||||
16.5 [cpp.error] | |||||
16.6 [cpp.pragma] | |||||
16.7 [cpp.null] | |||||
16.8 [cpp.predefined] | |||||
A [gram] | |||||
A.1 [gram.key] | |||||
A.2 [gram.lex] | |||||
A.3 [gram.basic] | |||||
A.4 [gram.expr] | |||||
A.5 [gram.stmt] | |||||
A.6 [gram.dcl] | |||||
A.7 [gram.decl] | |||||
A.8 [gram.class] | |||||
A.9 [gram.derived] | |||||
A.10 [gram.special] | |||||
A.11 [gram.over] | |||||
A.12 [gram.temp] | |||||
A.13 [gram.except] | |||||
A.14 [gram.cpp] | |||||
B [implimits] | |||||
C [diff] | |||||
C.1 [diff.iso] | |||||
C.1.1 [diff.lex] | |||||
C.1.2 [diff.basic] | |||||
C.1.3 [diff.expr] | |||||
C.1.4 [diff.stat] | |||||
C.1.5 [diff.dcl] | |||||
C.1.6 [diff.decl] | |||||
C.1.7 [diff.class] | |||||
C.1.8 [diff.special] | |||||
C.1.9 [diff.cpp] | |||||
C.2 [diff.library] | |||||
C.2.1 [diff.mods.to.headers] | |||||
C.2.2 [diff.mods.to.definitions] | |||||
C.2.2.2 [diff.wchar.t] | |||||
C.2.2.3 [diff.header.iso646.h] | |||||
C.2.2.4 [diff.null] | |||||
C.2.3 [diff.mods.to.declarations] | |||||
C.2.4 [diff.mods.to.behavior] | |||||
C.2.4.1 [diff.offsetof] | |||||
C.2.4.2 [diff.malloc] | |||||
D [depr] | |||||
D.1 [depr.incr.bool] | |||||
D.2 [depr.static] | |||||
D.3 [depr.access.dcl] | |||||
D.4 [depr.string] | |||||
D.5 [depr.c.headers] | |||||
E [extendid] | |||||
C++0x Features | |||||
Explicit conversion operators (N2437) | ✓ | No name mangling; ASTs don't contain calls to conversion operators |