blob: 37eb34e7776cb0e16e2461f345c02487644df5ea [file] [log] [blame]
Chris Lattnerf7b2e552007-08-25 06:57:03 +00001//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner959e5be2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattnerf7b2e552007-08-25 06:57:03 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the C++ Declaration portions of the Parser interfaces.
11//
12//===----------------------------------------------------------------------===//
13
Douglas Gregor696be932008-04-14 00:13:42 +000014#include "clang/Parse/Parser.h"
Chris Lattner545f39e2009-01-29 05:15:15 +000015#include "clang/Parse/ParseDiagnostic.h"
Douglas Gregorec93f442008-04-13 21:30:24 +000016#include "clang/Parse/DeclSpec.h"
Chris Lattnerf7b2e552007-08-25 06:57:03 +000017#include "clang/Parse/Scope.h"
Sebastian Redl6008ac32008-11-25 22:21:31 +000018#include "AstGuard.h"
Chris Lattnerf3375de2008-12-18 01:12:00 +000019#include "ExtensionRAIIObject.h"
Chris Lattnerf7b2e552007-08-25 06:57:03 +000020using namespace clang;
21
22/// ParseNamespace - We know that the current token is a namespace keyword. This
23/// may either be a top level namespace or a block-level namespace alias.
24///
25/// namespace-definition: [C++ 7.3: basic.namespace]
26/// named-namespace-definition
27/// unnamed-namespace-definition
28///
29/// unnamed-namespace-definition:
30/// 'namespace' attributes[opt] '{' namespace-body '}'
31///
32/// named-namespace-definition:
33/// original-namespace-definition
34/// extension-namespace-definition
35///
36/// original-namespace-definition:
37/// 'namespace' identifier attributes[opt] '{' namespace-body '}'
38///
39/// extension-namespace-definition:
40/// 'namespace' original-namespace-name '{' namespace-body '}'
41///
42/// namespace-alias-definition: [C++ 7.3.2: namespace.alias]
43/// 'namespace' identifier '=' qualified-namespace-specifier ';'
44///
Chris Lattner5261d0c2009-03-28 19:18:32 +000045Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context) {
Chris Lattner34a01ad2007-10-09 17:33:22 +000046 assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
Chris Lattnerf7b2e552007-08-25 06:57:03 +000047 SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'.
48
49 SourceLocation IdentLoc;
50 IdentifierInfo *Ident = 0;
51
Chris Lattner34a01ad2007-10-09 17:33:22 +000052 if (Tok.is(tok::identifier)) {
Chris Lattnerf7b2e552007-08-25 06:57:03 +000053 Ident = Tok.getIdentifierInfo();
54 IdentLoc = ConsumeToken(); // eat the identifier.
55 }
56
57 // Read label attributes, if present.
Chris Lattner5261d0c2009-03-28 19:18:32 +000058 Action::AttrTy *AttrList = 0;
Chris Lattner34a01ad2007-10-09 17:33:22 +000059 if (Tok.is(tok::kw___attribute))
Chris Lattnerf7b2e552007-08-25 06:57:03 +000060 // FIXME: save these somewhere.
61 AttrList = ParseAttributes();
62
Anders Carlssonf94cca22009-03-28 04:07:16 +000063 if (Tok.is(tok::equal))
Chris Lattnerf7b2e552007-08-25 06:57:03 +000064 // FIXME: Verify no attributes were present.
Anders Carlssonf94cca22009-03-28 04:07:16 +000065 return ParseNamespaceAlias(IdentLoc, Ident);
66
67 if (Tok.is(tok::l_brace)) {
Chris Lattnerf7b2e552007-08-25 06:57:03 +000068 SourceLocation LBrace = ConsumeBrace();
Argiris Kirtzidis03e6aaf2008-04-27 13:50:30 +000069
70 // Enter a scope for the namespace.
Douglas Gregor95d40792008-12-10 06:34:36 +000071 ParseScope NamespaceScope(this, Scope::DeclScope);
Argiris Kirtzidis03e6aaf2008-04-27 13:50:30 +000072
Chris Lattner5261d0c2009-03-28 19:18:32 +000073 DeclPtrTy NamespcDecl =
Argiris Kirtzidis03e6aaf2008-04-27 13:50:30 +000074 Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace);
75
Chris Lattnerc309ade2009-03-05 08:00:35 +000076 PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions,
77 PP.getSourceManager(),
78 "parsing namespace");
Chris Lattner696da202009-03-05 02:09:07 +000079
Argiris Kirtzidis03e6aaf2008-04-27 13:50:30 +000080 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof))
Chris Lattner9c135722007-08-25 18:15:16 +000081 ParseExternalDeclaration();
Chris Lattnerf7b2e552007-08-25 06:57:03 +000082
Argiris Kirtzidis5f21e592008-05-01 21:44:34 +000083 // Leave the namespace scope.
Douglas Gregor95d40792008-12-10 06:34:36 +000084 NamespaceScope.Exit();
Argiris Kirtzidis5f21e592008-05-01 21:44:34 +000085
Chris Lattnerf7b2e552007-08-25 06:57:03 +000086 SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
Argiris Kirtzidis03e6aaf2008-04-27 13:50:30 +000087 Actions.ActOnFinishNamespaceDef(NamespcDecl, RBrace);
88
Argiris Kirtzidis03e6aaf2008-04-27 13:50:30 +000089 return NamespcDecl;
Chris Lattnerf7b2e552007-08-25 06:57:03 +000090
Chris Lattnerf7b2e552007-08-25 06:57:03 +000091 } else {
Chris Lattnerf006a222008-11-18 07:48:38 +000092 Diag(Tok, Ident ? diag::err_expected_lbrace :
93 diag::err_expected_ident_lbrace);
Chris Lattnerf7b2e552007-08-25 06:57:03 +000094 }
95
Chris Lattner5261d0c2009-03-28 19:18:32 +000096 return DeclPtrTy();
Chris Lattnerf7b2e552007-08-25 06:57:03 +000097}
Chris Lattner806a5f52008-01-12 07:05:38 +000098
Anders Carlssonf94cca22009-03-28 04:07:16 +000099/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
100/// alias definition.
101///
Chris Lattner5261d0c2009-03-28 19:18:32 +0000102Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation AliasLoc,
103 IdentifierInfo *Alias) {
Anders Carlssonf94cca22009-03-28 04:07:16 +0000104 assert(Tok.is(tok::equal) && "Not equal token");
105
106 ConsumeToken(); // eat the '='.
107
108 CXXScopeSpec SS;
109 // Parse (optional) nested-name-specifier.
110 ParseOptionalCXXScopeSpecifier(SS);
111
112 if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
113 Diag(Tok, diag::err_expected_namespace_name);
114 // Skip to end of the definition and eat the ';'.
115 SkipUntil(tok::semi);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000116 return DeclPtrTy();
Anders Carlssonf94cca22009-03-28 04:07:16 +0000117 }
118
119 // Parse identifier.
120 IdentifierInfo *NamespaceName = Tok.getIdentifierInfo();
121 SourceLocation NamespaceLoc = ConsumeToken();
122
123 // Eat the ';'.
124 ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
125 "namespace name", tok::semi);
126
Anders Carlsson8cffcd62009-03-28 05:27:17 +0000127 return Actions.ActOnNamespaceAliasDef(CurScope, AliasLoc, Alias, SS,
128 NamespaceLoc, NamespaceName);
Anders Carlssonf94cca22009-03-28 04:07:16 +0000129}
130
Chris Lattner806a5f52008-01-12 07:05:38 +0000131/// ParseLinkage - We know that the current token is a string_literal
132/// and just before that, that extern was seen.
133///
134/// linkage-specification: [C++ 7.5p2: dcl.link]
135/// 'extern' string-literal '{' declaration-seq[opt] '}'
136/// 'extern' string-literal declaration
137///
Chris Lattner5261d0c2009-03-28 19:18:32 +0000138Parser::DeclPtrTy Parser::ParseLinkage(unsigned Context) {
Douglas Gregor61818c52008-11-21 16:10:08 +0000139 assert(Tok.is(tok::string_literal) && "Not a string literal!");
Chris Lattner806a5f52008-01-12 07:05:38 +0000140 llvm::SmallVector<char, 8> LangBuffer;
141 // LangBuffer is guaranteed to be big enough.
142 LangBuffer.resize(Tok.getLength());
143 const char *LangBufPtr = &LangBuffer[0];
144 unsigned StrSize = PP.getSpelling(Tok, LangBufPtr);
145
146 SourceLocation Loc = ConsumeStringToken();
Chris Lattner806a5f52008-01-12 07:05:38 +0000147
Douglas Gregord8028382009-01-05 19:45:36 +0000148 ParseScope LinkageScope(this, Scope::DeclScope);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000149 DeclPtrTy LinkageSpec
Douglas Gregord8028382009-01-05 19:45:36 +0000150 = Actions.ActOnStartLinkageSpecification(CurScope,
151 /*FIXME: */SourceLocation(),
152 Loc, LangBufPtr, StrSize,
153 Tok.is(tok::l_brace)? Tok.getLocation()
154 : SourceLocation());
155
156 if (Tok.isNot(tok::l_brace)) {
157 ParseDeclarationOrFunctionDefinition();
158 return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec,
159 SourceLocation());
Douglas Gregorad17e372008-12-16 22:23:02 +0000160 }
161
162 SourceLocation LBrace = ConsumeBrace();
Douglas Gregorad17e372008-12-16 22:23:02 +0000163 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
Douglas Gregord8028382009-01-05 19:45:36 +0000164 ParseExternalDeclaration();
Chris Lattner806a5f52008-01-12 07:05:38 +0000165 }
166
Douglas Gregorad17e372008-12-16 22:23:02 +0000167 SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
Douglas Gregord8028382009-01-05 19:45:36 +0000168 return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, RBrace);
Chris Lattner806a5f52008-01-12 07:05:38 +0000169}
Douglas Gregorec93f442008-04-13 21:30:24 +0000170
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000171/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
172/// using-directive. Assumes that current token is 'using'.
Chris Lattner5261d0c2009-03-28 19:18:32 +0000173Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context) {
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000174 assert(Tok.is(tok::kw_using) && "Not using token");
175
176 // Eat 'using'.
177 SourceLocation UsingLoc = ConsumeToken();
178
Chris Lattner08ab4162009-01-06 06:55:51 +0000179 if (Tok.is(tok::kw_namespace))
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000180 // Next token after 'using' is 'namespace' so it must be using-directive
181 return ParseUsingDirective(Context, UsingLoc);
Chris Lattner08ab4162009-01-06 06:55:51 +0000182
183 // Otherwise, it must be using-declaration.
184 return ParseUsingDeclaration(Context, UsingLoc);
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000185}
186
187/// ParseUsingDirective - Parse C++ using-directive, assumes
188/// that current token is 'namespace' and 'using' was already parsed.
189///
190/// using-directive: [C++ 7.3.p4: namespace.udir]
191/// 'using' 'namespace' ::[opt] nested-name-specifier[opt]
192/// namespace-name ;
193/// [GNU] using-directive:
194/// 'using' 'namespace' ::[opt] nested-name-specifier[opt]
195/// namespace-name attributes[opt] ;
196///
Chris Lattner5261d0c2009-03-28 19:18:32 +0000197Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
198 SourceLocation UsingLoc) {
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000199 assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
200
201 // Eat 'namespace'.
202 SourceLocation NamespcLoc = ConsumeToken();
203
204 CXXScopeSpec SS;
205 // Parse (optional) nested-name-specifier.
Chris Lattnerd706dc82009-01-06 06:59:53 +0000206 ParseOptionalCXXScopeSpecifier(SS);
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000207
208 AttributeList *AttrList = 0;
209 IdentifierInfo *NamespcName = 0;
210 SourceLocation IdentLoc = SourceLocation();
211
212 // Parse namespace-name.
Chris Lattner7898bf62009-01-06 07:27:21 +0000213 if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000214 Diag(Tok, diag::err_expected_namespace_name);
215 // If there was invalid namespace name, skip to end of decl, and eat ';'.
216 SkipUntil(tok::semi);
217 // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
Chris Lattner5261d0c2009-03-28 19:18:32 +0000218 return DeclPtrTy();
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000219 }
Chris Lattner7898bf62009-01-06 07:27:21 +0000220
221 // Parse identifier.
222 NamespcName = Tok.getIdentifierInfo();
223 IdentLoc = ConsumeToken();
224
225 // Parse (optional) attributes (most likely GNU strong-using extension).
226 if (Tok.is(tok::kw___attribute))
227 AttrList = ParseAttributes();
228
229 // Eat ';'.
230 ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
231 AttrList ? "attributes list" : "namespace name", tok::semi);
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000232
233 return Actions.ActOnUsingDirective(CurScope, UsingLoc, NamespcLoc, SS,
Chris Lattner7898bf62009-01-06 07:27:21 +0000234 IdentLoc, NamespcName, AttrList);
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000235}
236
237/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that
238/// 'using' was already seen.
239///
240/// using-declaration: [C++ 7.3.p3: namespace.udecl]
241/// 'using' 'typename'[opt] ::[opt] nested-name-specifier
242/// unqualified-id [TODO]
243/// 'using' :: unqualified-id [TODO]
244///
Chris Lattner5261d0c2009-03-28 19:18:32 +0000245Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
246 SourceLocation UsingLoc) {
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000247 assert(false && "Not implemented");
248 // FIXME: Implement parsing.
Chris Lattner5261d0c2009-03-28 19:18:32 +0000249 return DeclPtrTy();
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000250}
251
Anders Carlssonab041982009-03-11 16:27:10 +0000252/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
253///
254/// static_assert-declaration:
255/// static_assert ( constant-expression , string-literal ) ;
256///
Chris Lattner5261d0c2009-03-28 19:18:32 +0000257Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration() {
Anders Carlssonab041982009-03-11 16:27:10 +0000258 assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
259 SourceLocation StaticAssertLoc = ConsumeToken();
260
261 if (Tok.isNot(tok::l_paren)) {
262 Diag(Tok, diag::err_expected_lparen);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000263 return DeclPtrTy();
Anders Carlssonab041982009-03-11 16:27:10 +0000264 }
265
266 SourceLocation LParenLoc = ConsumeParen();
267
268 OwningExprResult AssertExpr(ParseConstantExpression());
269 if (AssertExpr.isInvalid()) {
270 SkipUntil(tok::semi);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000271 return DeclPtrTy();
Anders Carlssonab041982009-03-11 16:27:10 +0000272 }
273
Anders Carlssona24e8d52009-03-13 23:29:20 +0000274 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
Chris Lattner5261d0c2009-03-28 19:18:32 +0000275 return DeclPtrTy();
Anders Carlssona24e8d52009-03-13 23:29:20 +0000276
Anders Carlssonab041982009-03-11 16:27:10 +0000277 if (Tok.isNot(tok::string_literal)) {
278 Diag(Tok, diag::err_expected_string_literal);
279 SkipUntil(tok::semi);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000280 return DeclPtrTy();
Anders Carlssonab041982009-03-11 16:27:10 +0000281 }
282
283 OwningExprResult AssertMessage(ParseStringLiteralExpression());
284 if (AssertMessage.isInvalid())
Chris Lattner5261d0c2009-03-28 19:18:32 +0000285 return DeclPtrTy();
Anders Carlssonab041982009-03-11 16:27:10 +0000286
Anders Carlssonc45057a2009-03-15 18:44:04 +0000287 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Anders Carlssonab041982009-03-11 16:27:10 +0000288
289 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert);
290
Anders Carlssona24e8d52009-03-13 23:29:20 +0000291 return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, move(AssertExpr),
Anders Carlssonc45057a2009-03-15 18:44:04 +0000292 move(AssertMessage));
Anders Carlssonab041982009-03-11 16:27:10 +0000293}
294
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000295/// ParseClassName - Parse a C++ class-name, which names a class. Note
296/// that we only check that the result names a type; semantic analysis
297/// will need to verify that the type names a class. The result is
Douglas Gregor7bbed2a2009-02-25 23:52:28 +0000298/// either a type or NULL, depending on whether a type name was
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000299/// found.
300///
301/// class-name: [C++ 9.1]
302/// identifier
Douglas Gregor7bbed2a2009-02-25 23:52:28 +0000303/// simple-template-id
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000304///
Douglas Gregor7bbed2a2009-02-25 23:52:28 +0000305Parser::TypeTy *Parser::ParseClassName(SourceLocation &EndLocation,
306 const CXXScopeSpec *SS) {
307 // Check whether we have a template-id that names a type.
308 if (Tok.is(tok::annot_template_id)) {
309 TemplateIdAnnotation *TemplateId
310 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
311 if (TemplateId->Kind == TNK_Class_template) {
312 if (AnnotateTemplateIdTokenAsType(SS))
313 return 0;
314
315 assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
316 TypeTy *Type = Tok.getAnnotationValue();
317 EndLocation = Tok.getAnnotationEndLoc();
318 ConsumeToken();
319 return Type;
320 }
321
322 // Fall through to produce an error below.
323 }
324
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000325 if (Tok.isNot(tok::identifier)) {
Chris Lattnerf006a222008-11-18 07:48:38 +0000326 Diag(Tok, diag::err_expected_class_name);
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000327 return 0;
328 }
329
330 // We have an identifier; check whether it is actually a type.
Douglas Gregor1075a162009-02-04 17:00:24 +0000331 TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(),
332 Tok.getLocation(), CurScope, SS);
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000333 if (!Type) {
Chris Lattnerf006a222008-11-18 07:48:38 +0000334 Diag(Tok, diag::err_expected_class_name);
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000335 return 0;
336 }
337
338 // Consume the identifier.
Douglas Gregor7bbed2a2009-02-25 23:52:28 +0000339 EndLocation = ConsumeToken();
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000340 return Type;
341}
342
Douglas Gregorec93f442008-04-13 21:30:24 +0000343/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
344/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
345/// until we reach the start of a definition or see a token that
346/// cannot start a definition.
347///
348/// class-specifier: [C++ class]
349/// class-head '{' member-specification[opt] '}'
350/// class-head '{' member-specification[opt] '}' attributes[opt]
351/// class-head:
352/// class-key identifier[opt] base-clause[opt]
353/// class-key nested-name-specifier identifier base-clause[opt]
354/// class-key nested-name-specifier[opt] simple-template-id
355/// base-clause[opt]
356/// [GNU] class-key attributes[opt] identifier[opt] base-clause[opt]
357/// [GNU] class-key attributes[opt] nested-name-specifier
358/// identifier base-clause[opt]
359/// [GNU] class-key attributes[opt] nested-name-specifier[opt]
360/// simple-template-id base-clause[opt]
361/// class-key:
362/// 'class'
363/// 'struct'
364/// 'union'
365///
366/// elaborated-type-specifier: [C++ dcl.type.elab]
367/// class-key ::[opt] nested-name-specifier[opt] identifier
368/// class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
369/// simple-template-id
370///
371/// Note that the C++ class-specifier and elaborated-type-specifier,
372/// together, subsume the C99 struct-or-union-specifier:
373///
374/// struct-or-union-specifier: [C99 6.7.2.1]
375/// struct-or-union identifier[opt] '{' struct-contents '}'
376/// struct-or-union identifier
377/// [GNU] struct-or-union attributes[opt] identifier[opt] '{' struct-contents
378/// '}' attributes[opt]
379/// [GNU] struct-or-union attributes[opt] identifier
380/// struct-or-union:
381/// 'struct'
382/// 'union'
Douglas Gregor52473432008-12-24 02:52:09 +0000383void Parser::ParseClassSpecifier(DeclSpec &DS,
Douglas Gregor0c793bb2009-03-25 22:00:53 +0000384 TemplateParameterLists *TemplateParams,
385 AccessSpecifier AS) {
Douglas Gregorec93f442008-04-13 21:30:24 +0000386 assert((Tok.is(tok::kw_class) ||
387 Tok.is(tok::kw_struct) ||
388 Tok.is(tok::kw_union)) &&
389 "Not a class specifier");
390 DeclSpec::TST TagType =
391 Tok.is(tok::kw_class) ? DeclSpec::TST_class :
392 Tok.is(tok::kw_struct) ? DeclSpec::TST_struct :
393 DeclSpec::TST_union;
394
395 SourceLocation StartLoc = ConsumeToken();
396
397 AttributeList *Attr = 0;
398 // If attributes exist after tag, parse them.
399 if (Tok.is(tok::kw___attribute))
400 Attr = ParseAttributes();
401
Steve Naroffc5ab14f2008-12-24 20:59:21 +0000402 // If declspecs exist after tag, parse them.
403 if (Tok.is(tok::kw___declspec) && PP.getLangOptions().Microsoft)
404 FuzzyParseMicrosoftDeclSpec();
405
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000406 // Parse the (optional) nested-name-specifier.
407 CXXScopeSpec SS;
Douglas Gregor0c281a82009-02-25 19:37:18 +0000408 if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS))
409 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000410 Diag(Tok, diag::err_expected_ident);
Douglas Gregora08b6c72009-02-17 23:15:12 +0000411
412 // Parse the (optional) class name or simple-template-id.
Douglas Gregorec93f442008-04-13 21:30:24 +0000413 IdentifierInfo *Name = 0;
414 SourceLocation NameLoc;
Douglas Gregor0c281a82009-02-25 19:37:18 +0000415 TemplateIdAnnotation *TemplateId = 0;
Douglas Gregorec93f442008-04-13 21:30:24 +0000416 if (Tok.is(tok::identifier)) {
417 Name = Tok.getIdentifierInfo();
418 NameLoc = ConsumeToken();
Douglas Gregor0c281a82009-02-25 19:37:18 +0000419 } else if (Tok.is(tok::annot_template_id)) {
420 TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
421 NameLoc = ConsumeToken();
Douglas Gregora08b6c72009-02-17 23:15:12 +0000422
Douglas Gregor0c281a82009-02-25 19:37:18 +0000423 if (TemplateId->Kind != TNK_Class_template) {
424 // The template-name in the simple-template-id refers to
425 // something other than a class template. Give an appropriate
426 // error message and skip to the ';'.
427 SourceRange Range(NameLoc);
428 if (SS.isNotEmpty())
429 Range.setBegin(SS.getBeginLoc());
Douglas Gregora08b6c72009-02-17 23:15:12 +0000430
Douglas Gregor0c281a82009-02-25 19:37:18 +0000431 Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
432 << Name << static_cast<int>(TemplateId->Kind) << Range;
Douglas Gregora08b6c72009-02-17 23:15:12 +0000433
Douglas Gregor0c281a82009-02-25 19:37:18 +0000434 DS.SetTypeSpecError();
435 SkipUntil(tok::semi, false, true);
436 TemplateId->Destroy();
437 return;
Douglas Gregora08b6c72009-02-17 23:15:12 +0000438 }
Douglas Gregorec93f442008-04-13 21:30:24 +0000439 }
440
441 // There are three options here. If we have 'struct foo;', then
442 // this is a forward declaration. If we have 'struct foo {...' or
Douglas Gregor0c281a82009-02-25 19:37:18 +0000443 // 'struct foo :...' then this is a definition. Otherwise we have
Douglas Gregorec93f442008-04-13 21:30:24 +0000444 // something like 'struct foo xyz', a reference.
445 Action::TagKind TK;
446 if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon)))
447 TK = Action::TK_Definition;
448 else if (Tok.is(tok::semi))
449 TK = Action::TK_Declaration;
450 else
451 TK = Action::TK_Reference;
452
Douglas Gregor0c281a82009-02-25 19:37:18 +0000453 if (!Name && !TemplateId && TK != Action::TK_Definition) {
Douglas Gregorec93f442008-04-13 21:30:24 +0000454 // We have a declaration or reference to an anonymous class.
Chris Lattnerf006a222008-11-18 07:48:38 +0000455 Diag(StartLoc, diag::err_anon_type_definition)
456 << DeclSpec::getSpecifierName(TagType);
Douglas Gregorec93f442008-04-13 21:30:24 +0000457
458 // Skip the rest of this declarator, up until the comma or semicolon.
459 SkipUntil(tok::comma, true);
Douglas Gregor0c281a82009-02-25 19:37:18 +0000460
461 if (TemplateId)
462 TemplateId->Destroy();
Douglas Gregorec93f442008-04-13 21:30:24 +0000463 return;
464 }
465
Douglas Gregord406b032009-02-06 22:42:48 +0000466 // Create the tag portion of the class or class template.
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000467 Action::DeclResult TagOrTempResult;
Douglas Gregor0c281a82009-02-25 19:37:18 +0000468 if (TemplateId && TK != Action::TK_Reference) {
Douglas Gregora08b6c72009-02-17 23:15:12 +0000469 // Explicit specialization or class template partial
470 // specialization. Let semantic analysis decide.
Douglas Gregor0c281a82009-02-25 19:37:18 +0000471 ASTTemplateArgsPtr TemplateArgsPtr(Actions,
472 TemplateId->getTemplateArgs(),
473 TemplateId->getTemplateArgIsType(),
474 TemplateId->NumArgs);
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000475 TagOrTempResult
Douglas Gregora08b6c72009-02-17 23:15:12 +0000476 = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TK,
Douglas Gregor0c281a82009-02-25 19:37:18 +0000477 StartLoc, SS,
Chris Lattner5261d0c2009-03-28 19:18:32 +0000478 DeclPtrTy::make(TemplateId->Template),
Douglas Gregor0c281a82009-02-25 19:37:18 +0000479 TemplateId->TemplateNameLoc,
480 TemplateId->LAngleLoc,
481 TemplateArgsPtr,
482 TemplateId->getTemplateArgLocations(),
483 TemplateId->RAngleLoc,
484 Attr,
Douglas Gregora08b6c72009-02-17 23:15:12 +0000485 Action::MultiTemplateParamsArg(Actions,
486 TemplateParams? &(*TemplateParams)[0] : 0,
487 TemplateParams? TemplateParams->size() : 0));
Douglas Gregor0c281a82009-02-25 19:37:18 +0000488 TemplateId->Destroy();
489 } else if (TemplateParams && TK != Action::TK_Reference)
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000490 TagOrTempResult = Actions.ActOnClassTemplate(CurScope, TagType, TK,
491 StartLoc, SS, Name, NameLoc,
492 Attr,
Douglas Gregord406b032009-02-06 22:42:48 +0000493 Action::MultiTemplateParamsArg(Actions,
494 &(*TemplateParams)[0],
Anders Carlssoned20fb92009-03-26 00:52:18 +0000495 TemplateParams->size()),
496 AS);
Douglas Gregord406b032009-02-06 22:42:48 +0000497 else
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000498 TagOrTempResult = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS, Name,
Douglas Gregor0c793bb2009-03-25 22:00:53 +0000499 NameLoc, Attr, AS);
Douglas Gregorec93f442008-04-13 21:30:24 +0000500
501 // Parse the optional base clause (C++ only).
Chris Lattner31ccf0a2009-02-16 22:07:16 +0000502 if (getLang().CPlusPlus && Tok.is(tok::colon))
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000503 ParseBaseClause(TagOrTempResult.get());
Douglas Gregorec93f442008-04-13 21:30:24 +0000504
505 // If there is a body, parse it and inform the actions module.
506 if (Tok.is(tok::l_brace))
Argiris Kirtzidis38f16712008-07-01 10:37:29 +0000507 if (getLang().CPlusPlus)
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000508 ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
Argiris Kirtzidis38f16712008-07-01 10:37:29 +0000509 else
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000510 ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
Douglas Gregorec93f442008-04-13 21:30:24 +0000511 else if (TK == Action::TK_Definition) {
512 // FIXME: Complain that we have a base-specifier list but no
513 // definition.
Chris Lattnerf006a222008-11-18 07:48:38 +0000514 Diag(Tok, diag::err_expected_lbrace);
Douglas Gregorec93f442008-04-13 21:30:24 +0000515 }
516
517 const char *PrevSpec = 0;
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000518 if (TagOrTempResult.isInvalid())
Douglas Gregord406b032009-02-06 22:42:48 +0000519 DS.SetTypeSpecError();
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000520 else if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec,
Chris Lattner5261d0c2009-03-28 19:18:32 +0000521 TagOrTempResult.get().getAs<void>()))
Chris Lattnerf006a222008-11-18 07:48:38 +0000522 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
Douglas Gregorec93f442008-04-13 21:30:24 +0000523}
524
525/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
526///
527/// base-clause : [C++ class.derived]
528/// ':' base-specifier-list
529/// base-specifier-list:
530/// base-specifier '...'[opt]
531/// base-specifier-list ',' base-specifier '...'[opt]
Chris Lattner5261d0c2009-03-28 19:18:32 +0000532void Parser::ParseBaseClause(DeclPtrTy ClassDecl) {
Douglas Gregorec93f442008-04-13 21:30:24 +0000533 assert(Tok.is(tok::colon) && "Not a base clause");
534 ConsumeToken();
535
Douglas Gregorabed2172008-10-22 17:49:05 +0000536 // Build up an array of parsed base specifiers.
537 llvm::SmallVector<BaseTy *, 8> BaseInfo;
538
Douglas Gregorec93f442008-04-13 21:30:24 +0000539 while (true) {
540 // Parse a base-specifier.
Douglas Gregorabed2172008-10-22 17:49:05 +0000541 BaseResult Result = ParseBaseSpecifier(ClassDecl);
Douglas Gregor10a18fc2009-01-26 22:44:13 +0000542 if (Result.isInvalid()) {
Douglas Gregorec93f442008-04-13 21:30:24 +0000543 // Skip the rest of this base specifier, up until the comma or
544 // opening brace.
Douglas Gregorabed2172008-10-22 17:49:05 +0000545 SkipUntil(tok::comma, tok::l_brace, true, true);
546 } else {
547 // Add this to our array of base specifiers.
Douglas Gregor10a18fc2009-01-26 22:44:13 +0000548 BaseInfo.push_back(Result.get());
Douglas Gregorec93f442008-04-13 21:30:24 +0000549 }
550
551 // If the next token is a comma, consume it and keep reading
552 // base-specifiers.
553 if (Tok.isNot(tok::comma)) break;
554
555 // Consume the comma.
556 ConsumeToken();
557 }
Douglas Gregorabed2172008-10-22 17:49:05 +0000558
559 // Attach the base specifiers
560 Actions.ActOnBaseSpecifiers(ClassDecl, &BaseInfo[0], BaseInfo.size());
Douglas Gregorec93f442008-04-13 21:30:24 +0000561}
562
563/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
564/// one entry in the base class list of a class specifier, for example:
565/// class foo : public bar, virtual private baz {
566/// 'public bar' and 'virtual private baz' are each base-specifiers.
567///
568/// base-specifier: [C++ class.derived]
569/// ::[opt] nested-name-specifier[opt] class-name
570/// 'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt]
571/// class-name
572/// access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
573/// class-name
Chris Lattner5261d0c2009-03-28 19:18:32 +0000574Parser::BaseResult Parser::ParseBaseSpecifier(DeclPtrTy ClassDecl) {
Douglas Gregorec93f442008-04-13 21:30:24 +0000575 bool IsVirtual = false;
576 SourceLocation StartLoc = Tok.getLocation();
577
578 // Parse the 'virtual' keyword.
579 if (Tok.is(tok::kw_virtual)) {
580 ConsumeToken();
581 IsVirtual = true;
582 }
583
584 // Parse an (optional) access specifier.
585 AccessSpecifier Access = getAccessSpecifierIfPresent();
586 if (Access)
587 ConsumeToken();
588
589 // Parse the 'virtual' keyword (again!), in case it came after the
590 // access specifier.
591 if (Tok.is(tok::kw_virtual)) {
592 SourceLocation VirtualLoc = ConsumeToken();
593 if (IsVirtual) {
594 // Complain about duplicate 'virtual'
Chris Lattnerf006a222008-11-18 07:48:38 +0000595 Diag(VirtualLoc, diag::err_dup_virtual)
596 << SourceRange(VirtualLoc, VirtualLoc);
Douglas Gregorec93f442008-04-13 21:30:24 +0000597 }
598
599 IsVirtual = true;
600 }
601
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000602 // Parse optional '::' and optional nested-name-specifier.
603 CXXScopeSpec SS;
Chris Lattnerd706dc82009-01-06 06:59:53 +0000604 ParseOptionalCXXScopeSpecifier(SS);
Douglas Gregorec93f442008-04-13 21:30:24 +0000605
Douglas Gregorec93f442008-04-13 21:30:24 +0000606 // The location of the base class itself.
607 SourceLocation BaseLoc = Tok.getLocation();
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000608
609 // Parse the class-name.
Douglas Gregor7bbed2a2009-02-25 23:52:28 +0000610 SourceLocation EndLocation;
611 TypeTy *BaseType = ParseClassName(EndLocation, &SS);
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000612 if (!BaseType)
613 return true;
Douglas Gregorec93f442008-04-13 21:30:24 +0000614
615 // Find the complete source range for the base-specifier.
Douglas Gregor7bbed2a2009-02-25 23:52:28 +0000616 SourceRange Range(StartLoc, EndLocation);
Douglas Gregorec93f442008-04-13 21:30:24 +0000617
Douglas Gregorec93f442008-04-13 21:30:24 +0000618 // Notify semantic analysis that we have parsed a complete
619 // base-specifier.
Sebastian Redl6008ac32008-11-25 22:21:31 +0000620 return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
621 BaseType, BaseLoc);
Douglas Gregorec93f442008-04-13 21:30:24 +0000622}
623
624/// getAccessSpecifierIfPresent - Determine whether the next token is
625/// a C++ access-specifier.
626///
627/// access-specifier: [C++ class.derived]
628/// 'private'
629/// 'protected'
630/// 'public'
Douglas Gregor696be932008-04-14 00:13:42 +0000631AccessSpecifier Parser::getAccessSpecifierIfPresent() const
Douglas Gregorec93f442008-04-13 21:30:24 +0000632{
633 switch (Tok.getKind()) {
634 default: return AS_none;
635 case tok::kw_private: return AS_private;
636 case tok::kw_protected: return AS_protected;
637 case tok::kw_public: return AS_public;
638 }
639}
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000640
641/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
642///
643/// member-declaration:
644/// decl-specifier-seq[opt] member-declarator-list[opt] ';'
645/// function-definition ';'[opt]
646/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
647/// using-declaration [TODO]
Anders Carlssonab041982009-03-11 16:27:10 +0000648/// [C++0x] static_assert-declaration
Anders Carlssoned20fb92009-03-26 00:52:18 +0000649/// template-declaration
Chris Lattnerf3375de2008-12-18 01:12:00 +0000650/// [GNU] '__extension__' member-declaration
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000651///
652/// member-declarator-list:
653/// member-declarator
654/// member-declarator-list ',' member-declarator
655///
656/// member-declarator:
657/// declarator pure-specifier[opt]
658/// declarator constant-initializer[opt]
659/// identifier[opt] ':' constant-expression
660///
661/// pure-specifier: [TODO]
662/// '= 0'
663///
664/// constant-initializer:
665/// '=' constant-expression
666///
Chris Lattner5261d0c2009-03-28 19:18:32 +0000667Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
Anders Carlssonab041982009-03-11 16:27:10 +0000668 // static_assert-declaration
669 if (Tok.is(tok::kw_static_assert))
670 return ParseStaticAssertDeclaration();
671
Anders Carlssoned20fb92009-03-26 00:52:18 +0000672 if (Tok.is(tok::kw_template))
673 return ParseTemplateDeclarationOrSpecialization(Declarator::MemberContext,
674 AS);
675
Chris Lattnerf3375de2008-12-18 01:12:00 +0000676 // Handle: member-declaration ::= '__extension__' member-declaration
677 if (Tok.is(tok::kw___extension__)) {
678 // __extension__ silences extension warnings in the subexpression.
679 ExtensionRAIIObject O(Diags); // Use RAII to do this.
680 ConsumeToken();
681 return ParseCXXClassMemberDeclaration(AS);
682 }
683
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000684 SourceLocation DSStart = Tok.getLocation();
685 // decl-specifier-seq:
686 // Parse the common declaration-specifiers piece.
687 DeclSpec DS;
Douglas Gregor0c793bb2009-03-25 22:00:53 +0000688 ParseDeclarationSpecifiers(DS, 0, AS);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000689
690 if (Tok.is(tok::semi)) {
691 ConsumeToken();
692 // C++ 9.2p7: The member-declarator-list can be omitted only after a
693 // class-specifier or an enum-specifier or in a friend declaration.
694 // FIXME: Friend declarations.
695 switch (DS.getTypeSpecType()) {
696 case DeclSpec::TST_struct:
697 case DeclSpec::TST_union:
698 case DeclSpec::TST_class:
699 case DeclSpec::TST_enum:
700 return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
701 default:
702 Diag(DSStart, diag::err_no_declarators);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000703 return DeclPtrTy();
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000704 }
705 }
Argiris Kirtzidis38f16712008-07-01 10:37:29 +0000706
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000707 Declarator DeclaratorInfo(DS, Declarator::MemberContext);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000708
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000709 if (Tok.isNot(tok::colon)) {
710 // Parse the first declarator.
711 ParseDeclarator(DeclaratorInfo);
712 // Error parsing the declarator?
Douglas Gregor6704b312008-11-17 22:58:34 +0000713 if (!DeclaratorInfo.hasName()) {
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000714 // If so, skip until the semi-colon or a }.
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000715 SkipUntil(tok::r_brace, true);
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000716 if (Tok.is(tok::semi))
717 ConsumeToken();
Chris Lattner5261d0c2009-03-28 19:18:32 +0000718 return DeclPtrTy();
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000719 }
720
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000721 // function-definition:
Douglas Gregora65e8dd2008-11-05 04:29:56 +0000722 if (Tok.is(tok::l_brace)
723 || (DeclaratorInfo.isFunctionDeclarator() && Tok.is(tok::colon))) {
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000724 if (!DeclaratorInfo.isFunctionDeclarator()) {
725 Diag(Tok, diag::err_func_def_no_params);
726 ConsumeBrace();
727 SkipUntil(tok::r_brace, true);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000728 return DeclPtrTy();
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000729 }
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000730
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000731 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
732 Diag(Tok, diag::err_function_declared_typedef);
733 // This recovery skips the entire function body. It would be nice
734 // to simply call ParseCXXInlineMethodDef() below, however Sema
735 // assumes the declarator represents a function, not a typedef.
736 ConsumeBrace();
737 SkipUntil(tok::r_brace, true);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000738 return DeclPtrTy();
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000739 }
740
741 return ParseCXXInlineMethodDef(AS, DeclaratorInfo);
742 }
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000743 }
744
745 // member-declarator-list:
746 // member-declarator
747 // member-declarator-list ',' member-declarator
748
Chris Lattner5261d0c2009-03-28 19:18:32 +0000749 DeclPtrTy LastDeclInGroup;
Sebastian Redl62261042008-12-09 20:22:58 +0000750 OwningExprResult BitfieldSize(Actions);
751 OwningExprResult Init(Actions);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000752
753 while (1) {
754
755 // member-declarator:
756 // declarator pure-specifier[opt]
757 // declarator constant-initializer[opt]
758 // identifier[opt] ':' constant-expression
759
760 if (Tok.is(tok::colon)) {
761 ConsumeToken();
Sebastian Redlbb4dae72008-12-09 13:15:23 +0000762 BitfieldSize = ParseConstantExpression();
763 if (BitfieldSize.isInvalid())
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000764 SkipUntil(tok::comma, true, true);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000765 }
766
767 // pure-specifier:
768 // '= 0'
769 //
770 // constant-initializer:
771 // '=' constant-expression
772
773 if (Tok.is(tok::equal)) {
774 ConsumeToken();
Sebastian Redlbb4dae72008-12-09 13:15:23 +0000775 Init = ParseInitializer();
776 if (Init.isInvalid())
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000777 SkipUntil(tok::comma, true, true);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000778 }
779
780 // If attributes exist after the declarator, parse them.
Sebastian Redl0c986032009-02-09 18:23:29 +0000781 if (Tok.is(tok::kw___attribute)) {
782 SourceLocation Loc;
783 AttributeList *AttrList = ParseAttributes(&Loc);
784 DeclaratorInfo.AddAttributes(AttrList, Loc);
785 }
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000786
Argiris Kirtzidis38f16712008-07-01 10:37:29 +0000787 // NOTE: If Sema is the Action module and declarator is an instance field,
788 // this call will *not* return the created decl; LastDeclInGroup will be
789 // returned instead.
790 // See Sema::ActOnCXXMemberDeclarator for details.
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000791 LastDeclInGroup = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
792 DeclaratorInfo,
Sebastian Redl6f1ee232008-12-10 00:02:53 +0000793 BitfieldSize.release(),
794 Init.release(),
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000795 LastDeclInGroup);
796
Douglas Gregor605de8d2008-12-16 21:30:33 +0000797 if (DeclaratorInfo.isFunctionDeclarator() &&
798 DeclaratorInfo.getDeclSpec().getStorageClassSpec()
799 != DeclSpec::SCS_typedef) {
800 // We just declared a member function. If this member function
801 // has any default arguments, we'll need to parse them later.
802 LateParsedMethodDeclaration *LateMethod = 0;
803 DeclaratorChunk::FunctionTypeInfo &FTI
804 = DeclaratorInfo.getTypeObject(0).Fun;
805 for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
806 if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
807 if (!LateMethod) {
808 // Push this method onto the stack of late-parsed method
809 // declarations.
810 getCurTopClassStack().MethodDecls.push_back(
811 LateParsedMethodDeclaration(LastDeclInGroup));
812 LateMethod = &getCurTopClassStack().MethodDecls.back();
813
814 // Add all of the parameters prior to this one (they don't
815 // have default arguments).
816 LateMethod->DefaultArgs.reserve(FTI.NumArgs);
817 for (unsigned I = 0; I < ParamIdx; ++I)
818 LateMethod->DefaultArgs.push_back(
819 LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param));
820 }
821
822 // Add this parameter to the list of parameters (it or may
823 // not have a default argument).
824 LateMethod->DefaultArgs.push_back(
825 LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
826 FTI.ArgInfo[ParamIdx].DefaultArgTokens));
827 }
828 }
829 }
830
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000831 // If we don't have a comma, it is either the end of the list (a ';')
832 // or an error, bail out.
833 if (Tok.isNot(tok::comma))
834 break;
835
836 // Consume the comma.
837 ConsumeToken();
838
839 // Parse the next declarator.
840 DeclaratorInfo.clear();
Sebastian Redl62261042008-12-09 20:22:58 +0000841 BitfieldSize = 0;
842 Init = 0;
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000843
844 // Attributes are only allowed on the second declarator.
Sebastian Redl0c986032009-02-09 18:23:29 +0000845 if (Tok.is(tok::kw___attribute)) {
846 SourceLocation Loc;
847 AttributeList *AttrList = ParseAttributes(&Loc);
848 DeclaratorInfo.AddAttributes(AttrList, Loc);
849 }
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000850
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000851 if (Tok.isNot(tok::colon))
852 ParseDeclarator(DeclaratorInfo);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000853 }
854
855 if (Tok.is(tok::semi)) {
856 ConsumeToken();
857 // Reverse the chain list.
858 return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
859 }
860
861 Diag(Tok, diag::err_expected_semi_decl_list);
862 // Skip to end of block or statement
863 SkipUntil(tok::r_brace, true, true);
864 if (Tok.is(tok::semi))
865 ConsumeToken();
Chris Lattner5261d0c2009-03-28 19:18:32 +0000866 return DeclPtrTy();
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000867}
868
869/// ParseCXXMemberSpecification - Parse the class definition.
870///
871/// member-specification:
872/// member-declaration member-specification[opt]
873/// access-specifier ':' member-specification[opt]
874///
875void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
Chris Lattner5261d0c2009-03-28 19:18:32 +0000876 unsigned TagType, DeclPtrTy TagDecl) {
Sanjiv Guptafa451432008-10-31 09:52:39 +0000877 assert((TagType == DeclSpec::TST_struct ||
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000878 TagType == DeclSpec::TST_union ||
Sanjiv Guptafa451432008-10-31 09:52:39 +0000879 TagType == DeclSpec::TST_class) && "Invalid TagType!");
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000880
Chris Lattnerc309ade2009-03-05 08:00:35 +0000881 PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
882 PP.getSourceManager(),
883 "parsing struct/union/class body");
Chris Lattner7efd75e2009-03-05 02:25:03 +0000884
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000885 SourceLocation LBraceLoc = ConsumeBrace();
886
Douglas Gregorcab994d2009-01-09 22:42:13 +0000887 if (!CurScope->isClassScope() && // Not about to define a nested class.
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000888 CurScope->isInCXXInlineMethodScope()) {
889 // We will define a local class of an inline method.
890 // Push a new LexedMethodsForTopClass for its inline methods.
891 PushTopClassStack();
892 }
893
894 // Enter a scope for the class.
Douglas Gregorcab994d2009-01-09 22:42:13 +0000895 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000896
Douglas Gregord406b032009-02-06 22:42:48 +0000897 if (TagDecl)
898 Actions.ActOnTagStartDefinition(CurScope, TagDecl);
899 else {
900 SkipUntil(tok::r_brace, false, false);
901 return;
902 }
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000903
904 // C++ 11p3: Members of a class defined with the keyword class are private
905 // by default. Members of a class defined with the keywords struct or union
906 // are public by default.
907 AccessSpecifier CurAS;
908 if (TagType == DeclSpec::TST_class)
909 CurAS = AS_private;
910 else
911 CurAS = AS_public;
912
913 // While we still have something to read, read the member-declarations.
914 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
915 // Each iteration of this loop reads one member-declaration.
916
917 // Check for extraneous top-level semicolon.
918 if (Tok.is(tok::semi)) {
919 Diag(Tok, diag::ext_extra_struct_semi);
920 ConsumeToken();
921 continue;
922 }
923
924 AccessSpecifier AS = getAccessSpecifierIfPresent();
925 if (AS != AS_none) {
926 // Current token is a C++ access specifier.
927 CurAS = AS;
928 ConsumeToken();
929 ExpectAndConsume(tok::colon, diag::err_expected_colon);
930 continue;
931 }
932
933 // Parse all the comma separated declarators.
934 ParseCXXClassMemberDeclaration(CurAS);
935 }
936
937 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
938
939 AttributeList *AttrList = 0;
940 // If attributes exist after class contents, parse them.
941 if (Tok.is(tok::kw___attribute))
942 AttrList = ParseAttributes(); // FIXME: where should I put them?
943
944 Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl,
945 LBraceLoc, RBraceLoc);
946
947 // C++ 9.2p2: Within the class member-specification, the class is regarded as
948 // complete within function bodies, default arguments,
949 // exception-specifications, and constructor ctor-initializers (including
950 // such things in nested classes).
951 //
Douglas Gregor605de8d2008-12-16 21:30:33 +0000952 // FIXME: Only function bodies and constructor ctor-initializers are
953 // parsed correctly, fix the rest.
Douglas Gregorcab994d2009-01-09 22:42:13 +0000954 if (!CurScope->getParent()->isClassScope()) {
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000955 // We are not inside a nested class. This class and its nested classes
Douglas Gregor605de8d2008-12-16 21:30:33 +0000956 // are complete and we can parse the delayed portions of method
957 // declarations and the lexed inline method definitions.
958 ParseLexedMethodDeclarations();
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000959 ParseLexedMethodDefs();
960
961 // For a local class of inline method, pop the LexedMethodsForTopClass that
962 // was previously pushed.
963
Sanjiv Guptafa451432008-10-31 09:52:39 +0000964 assert((CurScope->isInCXXInlineMethodScope() ||
965 TopClassStacks.size() == 1) &&
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000966 "MethodLexers not getting popped properly!");
967 if (CurScope->isInCXXInlineMethodScope())
968 PopTopClassStack();
969 }
970
971 // Leave the class scope.
Douglas Gregor95d40792008-12-10 06:34:36 +0000972 ClassScope.Exit();
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000973
Douglas Gregordb568cf2009-01-08 20:45:30 +0000974 Actions.ActOnTagFinishDefinition(CurScope, TagDecl);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000975}
Douglas Gregora65e8dd2008-11-05 04:29:56 +0000976
977/// ParseConstructorInitializer - Parse a C++ constructor initializer,
978/// which explicitly initializes the members or base classes of a
979/// class (C++ [class.base.init]). For example, the three initializers
980/// after the ':' in the Derived constructor below:
981///
982/// @code
983/// class Base { };
984/// class Derived : Base {
985/// int x;
986/// float f;
987/// public:
988/// Derived(float f) : Base(), x(17), f(f) { }
989/// };
990/// @endcode
991///
992/// [C++] ctor-initializer:
993/// ':' mem-initializer-list
994///
995/// [C++] mem-initializer-list:
996/// mem-initializer
997/// mem-initializer , mem-initializer-list
Chris Lattner5261d0c2009-03-28 19:18:32 +0000998void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) {
Douglas Gregora65e8dd2008-11-05 04:29:56 +0000999 assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
1000
1001 SourceLocation ColonLoc = ConsumeToken();
1002
1003 llvm::SmallVector<MemInitTy*, 4> MemInitializers;
1004
1005 do {
1006 MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
Douglas Gregor10a18fc2009-01-26 22:44:13 +00001007 if (!MemInit.isInvalid())
1008 MemInitializers.push_back(MemInit.get());
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001009
1010 if (Tok.is(tok::comma))
1011 ConsumeToken();
1012 else if (Tok.is(tok::l_brace))
1013 break;
1014 else {
1015 // Skip over garbage, until we get to '{'. Don't eat the '{'.
1016 SkipUntil(tok::l_brace, true, true);
1017 break;
1018 }
1019 } while (true);
1020
1021 Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc,
1022 &MemInitializers[0], MemInitializers.size());
1023}
1024
1025/// ParseMemInitializer - Parse a C++ member initializer, which is
1026/// part of a constructor initializer that explicitly initializes one
1027/// member or base class (C++ [class.base.init]). See
1028/// ParseConstructorInitializer for an example.
1029///
1030/// [C++] mem-initializer:
1031/// mem-initializer-id '(' expression-list[opt] ')'
1032///
1033/// [C++] mem-initializer-id:
1034/// '::'[opt] nested-name-specifier[opt] class-name
1035/// identifier
Chris Lattner5261d0c2009-03-28 19:18:32 +00001036Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001037 // FIXME: parse '::'[opt] nested-name-specifier[opt]
1038
1039 if (Tok.isNot(tok::identifier)) {
Chris Lattnerf006a222008-11-18 07:48:38 +00001040 Diag(Tok, diag::err_expected_member_or_base_name);
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001041 return true;
1042 }
1043
1044 // Get the identifier. This may be a member name or a class name,
1045 // but we'll let the semantic analysis determine which it is.
1046 IdentifierInfo *II = Tok.getIdentifierInfo();
1047 SourceLocation IdLoc = ConsumeToken();
1048
1049 // Parse the '('.
1050 if (Tok.isNot(tok::l_paren)) {
Chris Lattnerf006a222008-11-18 07:48:38 +00001051 Diag(Tok, diag::err_expected_lparen);
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001052 return true;
1053 }
1054 SourceLocation LParenLoc = ConsumeParen();
1055
1056 // Parse the optional expression-list.
Sebastian Redl6008ac32008-11-25 22:21:31 +00001057 ExprVector ArgExprs(Actions);
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001058 CommaLocsTy CommaLocs;
1059 if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
1060 SkipUntil(tok::r_paren);
1061 return true;
1062 }
1063
1064 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1065
Sebastian Redl6008ac32008-11-25 22:21:31 +00001066 return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, II, IdLoc,
1067 LParenLoc, ArgExprs.take(),
1068 ArgExprs.size(), &CommaLocs[0], RParenLoc);
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001069}
Douglas Gregor90a2c972008-11-25 03:22:00 +00001070
1071/// ParseExceptionSpecification - Parse a C++ exception-specification
1072/// (C++ [except.spec]).
1073///
Douglas Gregor9ed9ac82008-12-01 18:00:20 +00001074/// exception-specification:
1075/// 'throw' '(' type-id-list [opt] ')'
1076/// [MS] 'throw' '(' '...' ')'
Douglas Gregor90a2c972008-11-25 03:22:00 +00001077///
Douglas Gregor9ed9ac82008-12-01 18:00:20 +00001078/// type-id-list:
1079/// type-id
1080/// type-id-list ',' type-id
Douglas Gregor90a2c972008-11-25 03:22:00 +00001081///
Sebastian Redl0c986032009-02-09 18:23:29 +00001082bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc) {
Douglas Gregor90a2c972008-11-25 03:22:00 +00001083 assert(Tok.is(tok::kw_throw) && "expected throw");
1084
1085 SourceLocation ThrowLoc = ConsumeToken();
1086
1087 if (!Tok.is(tok::l_paren)) {
1088 return Diag(Tok, diag::err_expected_lparen_after) << "throw";
1089 }
1090 SourceLocation LParenLoc = ConsumeParen();
1091
Douglas Gregor9ed9ac82008-12-01 18:00:20 +00001092 // Parse throw(...), a Microsoft extension that means "this function
1093 // can throw anything".
1094 if (Tok.is(tok::ellipsis)) {
1095 SourceLocation EllipsisLoc = ConsumeToken();
1096 if (!getLang().Microsoft)
1097 Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
Sebastian Redl0c986032009-02-09 18:23:29 +00001098 EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Douglas Gregor9ed9ac82008-12-01 18:00:20 +00001099 return false;
1100 }
1101
Douglas Gregor90a2c972008-11-25 03:22:00 +00001102 // Parse the sequence of type-ids.
1103 while (Tok.isNot(tok::r_paren)) {
1104 ParseTypeName();
1105 if (Tok.is(tok::comma))
1106 ConsumeToken();
1107 else
1108 break;
1109 }
1110
Sebastian Redl0c986032009-02-09 18:23:29 +00001111 EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Douglas Gregor90a2c972008-11-25 03:22:00 +00001112 return false;
1113}