blob: 121bf04bc33c7eea29b6050da206401501fbdde2 [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///
45Parser::DeclTy *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.
58 DeclTy *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
73 DeclTy *NamespcDecl =
74 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
96 return 0;
97}
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///
102Parser::DeclTy *Parser::ParseNamespaceAlias(SourceLocation AliasLoc,
103 IdentifierInfo *Alias) {
104 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);
116 return 0;
117 }
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///
138Parser::DeclTy *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);
149 DeclTy *LinkageSpec
150 = 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 Lattner08ab4162009-01-06 06:55:51 +0000173Parser::DeclTy *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///
197Parser::DeclTy *Parser::ParseUsingDirective(unsigned Context,
198 SourceLocation UsingLoc) {
199 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?
218 return 0;
219 }
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///
245Parser::DeclTy *Parser::ParseUsingDeclaration(unsigned Context,
246 SourceLocation UsingLoc) {
247 assert(false && "Not implemented");
248 // FIXME: Implement parsing.
249 return 0;
250}
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///
257Parser::DeclTy *Parser::ParseStaticAssertDeclaration() {
258 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);
263 return 0;
264 }
265
266 SourceLocation LParenLoc = ConsumeParen();
267
268 OwningExprResult AssertExpr(ParseConstantExpression());
269 if (AssertExpr.isInvalid()) {
270 SkipUntil(tok::semi);
271 return 0;
272 }
273
Anders Carlssona24e8d52009-03-13 23:29:20 +0000274 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
Anders Carlssonab041982009-03-11 16:27:10 +0000275 return 0;
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);
280 return 0;
281 }
282
283 OwningExprResult AssertMessage(ParseStringLiteralExpression());
284 if (AssertMessage.isInvalid())
285 return 0;
286
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,
478 TemplateId->Template,
479 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,
521 TagOrTempResult.get()))
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]
532void Parser::ParseBaseClause(DeclTy *ClassDecl)
533{
534 assert(Tok.is(tok::colon) && "Not a base clause");
535 ConsumeToken();
536
Douglas Gregorabed2172008-10-22 17:49:05 +0000537 // Build up an array of parsed base specifiers.
538 llvm::SmallVector<BaseTy *, 8> BaseInfo;
539
Douglas Gregorec93f442008-04-13 21:30:24 +0000540 while (true) {
541 // Parse a base-specifier.
Douglas Gregorabed2172008-10-22 17:49:05 +0000542 BaseResult Result = ParseBaseSpecifier(ClassDecl);
Douglas Gregor10a18fc2009-01-26 22:44:13 +0000543 if (Result.isInvalid()) {
Douglas Gregorec93f442008-04-13 21:30:24 +0000544 // Skip the rest of this base specifier, up until the comma or
545 // opening brace.
Douglas Gregorabed2172008-10-22 17:49:05 +0000546 SkipUntil(tok::comma, tok::l_brace, true, true);
547 } else {
548 // Add this to our array of base specifiers.
Douglas Gregor10a18fc2009-01-26 22:44:13 +0000549 BaseInfo.push_back(Result.get());
Douglas Gregorec93f442008-04-13 21:30:24 +0000550 }
551
552 // If the next token is a comma, consume it and keep reading
553 // base-specifiers.
554 if (Tok.isNot(tok::comma)) break;
555
556 // Consume the comma.
557 ConsumeToken();
558 }
Douglas Gregorabed2172008-10-22 17:49:05 +0000559
560 // Attach the base specifiers
561 Actions.ActOnBaseSpecifiers(ClassDecl, &BaseInfo[0], BaseInfo.size());
Douglas Gregorec93f442008-04-13 21:30:24 +0000562}
563
564/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
565/// one entry in the base class list of a class specifier, for example:
566/// class foo : public bar, virtual private baz {
567/// 'public bar' and 'virtual private baz' are each base-specifiers.
568///
569/// base-specifier: [C++ class.derived]
570/// ::[opt] nested-name-specifier[opt] class-name
571/// 'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt]
572/// class-name
573/// access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
574/// class-name
Douglas Gregorabed2172008-10-22 17:49:05 +0000575Parser::BaseResult Parser::ParseBaseSpecifier(DeclTy *ClassDecl)
Douglas Gregorec93f442008-04-13 21:30:24 +0000576{
577 bool IsVirtual = false;
578 SourceLocation StartLoc = Tok.getLocation();
579
580 // Parse the 'virtual' keyword.
581 if (Tok.is(tok::kw_virtual)) {
582 ConsumeToken();
583 IsVirtual = true;
584 }
585
586 // Parse an (optional) access specifier.
587 AccessSpecifier Access = getAccessSpecifierIfPresent();
588 if (Access)
589 ConsumeToken();
590
591 // Parse the 'virtual' keyword (again!), in case it came after the
592 // access specifier.
593 if (Tok.is(tok::kw_virtual)) {
594 SourceLocation VirtualLoc = ConsumeToken();
595 if (IsVirtual) {
596 // Complain about duplicate 'virtual'
Chris Lattnerf006a222008-11-18 07:48:38 +0000597 Diag(VirtualLoc, diag::err_dup_virtual)
598 << SourceRange(VirtualLoc, VirtualLoc);
Douglas Gregorec93f442008-04-13 21:30:24 +0000599 }
600
601 IsVirtual = true;
602 }
603
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000604 // Parse optional '::' and optional nested-name-specifier.
605 CXXScopeSpec SS;
Chris Lattnerd706dc82009-01-06 06:59:53 +0000606 ParseOptionalCXXScopeSpecifier(SS);
Douglas Gregorec93f442008-04-13 21:30:24 +0000607
Douglas Gregorec93f442008-04-13 21:30:24 +0000608 // The location of the base class itself.
609 SourceLocation BaseLoc = Tok.getLocation();
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000610
611 // Parse the class-name.
Douglas Gregor7bbed2a2009-02-25 23:52:28 +0000612 SourceLocation EndLocation;
613 TypeTy *BaseType = ParseClassName(EndLocation, &SS);
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000614 if (!BaseType)
615 return true;
Douglas Gregorec93f442008-04-13 21:30:24 +0000616
617 // Find the complete source range for the base-specifier.
Douglas Gregor7bbed2a2009-02-25 23:52:28 +0000618 SourceRange Range(StartLoc, EndLocation);
Douglas Gregorec93f442008-04-13 21:30:24 +0000619
Douglas Gregorec93f442008-04-13 21:30:24 +0000620 // Notify semantic analysis that we have parsed a complete
621 // base-specifier.
Sebastian Redl6008ac32008-11-25 22:21:31 +0000622 return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
623 BaseType, BaseLoc);
Douglas Gregorec93f442008-04-13 21:30:24 +0000624}
625
626/// getAccessSpecifierIfPresent - Determine whether the next token is
627/// a C++ access-specifier.
628///
629/// access-specifier: [C++ class.derived]
630/// 'private'
631/// 'protected'
632/// 'public'
Douglas Gregor696be932008-04-14 00:13:42 +0000633AccessSpecifier Parser::getAccessSpecifierIfPresent() const
Douglas Gregorec93f442008-04-13 21:30:24 +0000634{
635 switch (Tok.getKind()) {
636 default: return AS_none;
637 case tok::kw_private: return AS_private;
638 case tok::kw_protected: return AS_protected;
639 case tok::kw_public: return AS_public;
640 }
641}
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000642
643/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
644///
645/// member-declaration:
646/// decl-specifier-seq[opt] member-declarator-list[opt] ';'
647/// function-definition ';'[opt]
648/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
649/// using-declaration [TODO]
Anders Carlssonab041982009-03-11 16:27:10 +0000650/// [C++0x] static_assert-declaration
Anders Carlssoned20fb92009-03-26 00:52:18 +0000651/// template-declaration
Chris Lattnerf3375de2008-12-18 01:12:00 +0000652/// [GNU] '__extension__' member-declaration
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000653///
654/// member-declarator-list:
655/// member-declarator
656/// member-declarator-list ',' member-declarator
657///
658/// member-declarator:
659/// declarator pure-specifier[opt]
660/// declarator constant-initializer[opt]
661/// identifier[opt] ':' constant-expression
662///
663/// pure-specifier: [TODO]
664/// '= 0'
665///
666/// constant-initializer:
667/// '=' constant-expression
668///
669Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
Anders Carlssonab041982009-03-11 16:27:10 +0000670 // static_assert-declaration
671 if (Tok.is(tok::kw_static_assert))
672 return ParseStaticAssertDeclaration();
673
Anders Carlssoned20fb92009-03-26 00:52:18 +0000674 if (Tok.is(tok::kw_template))
675 return ParseTemplateDeclarationOrSpecialization(Declarator::MemberContext,
676 AS);
677
Chris Lattnerf3375de2008-12-18 01:12:00 +0000678 // Handle: member-declaration ::= '__extension__' member-declaration
679 if (Tok.is(tok::kw___extension__)) {
680 // __extension__ silences extension warnings in the subexpression.
681 ExtensionRAIIObject O(Diags); // Use RAII to do this.
682 ConsumeToken();
683 return ParseCXXClassMemberDeclaration(AS);
684 }
685
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000686 SourceLocation DSStart = Tok.getLocation();
687 // decl-specifier-seq:
688 // Parse the common declaration-specifiers piece.
689 DeclSpec DS;
Douglas Gregor0c793bb2009-03-25 22:00:53 +0000690 ParseDeclarationSpecifiers(DS, 0, AS);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000691
692 if (Tok.is(tok::semi)) {
693 ConsumeToken();
694 // C++ 9.2p7: The member-declarator-list can be omitted only after a
695 // class-specifier or an enum-specifier or in a friend declaration.
696 // FIXME: Friend declarations.
697 switch (DS.getTypeSpecType()) {
698 case DeclSpec::TST_struct:
699 case DeclSpec::TST_union:
700 case DeclSpec::TST_class:
701 case DeclSpec::TST_enum:
702 return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
703 default:
704 Diag(DSStart, diag::err_no_declarators);
705 return 0;
706 }
707 }
Argiris Kirtzidis38f16712008-07-01 10:37:29 +0000708
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000709 Declarator DeclaratorInfo(DS, Declarator::MemberContext);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000710
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000711 if (Tok.isNot(tok::colon)) {
712 // Parse the first declarator.
713 ParseDeclarator(DeclaratorInfo);
714 // Error parsing the declarator?
Douglas Gregor6704b312008-11-17 22:58:34 +0000715 if (!DeclaratorInfo.hasName()) {
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000716 // If so, skip until the semi-colon or a }.
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000717 SkipUntil(tok::r_brace, true);
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000718 if (Tok.is(tok::semi))
719 ConsumeToken();
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000720 return 0;
721 }
722
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000723 // function-definition:
Douglas Gregora65e8dd2008-11-05 04:29:56 +0000724 if (Tok.is(tok::l_brace)
725 || (DeclaratorInfo.isFunctionDeclarator() && Tok.is(tok::colon))) {
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000726 if (!DeclaratorInfo.isFunctionDeclarator()) {
727 Diag(Tok, diag::err_func_def_no_params);
728 ConsumeBrace();
729 SkipUntil(tok::r_brace, true);
730 return 0;
731 }
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000732
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000733 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
734 Diag(Tok, diag::err_function_declared_typedef);
735 // This recovery skips the entire function body. It would be nice
736 // to simply call ParseCXXInlineMethodDef() below, however Sema
737 // assumes the declarator represents a function, not a typedef.
738 ConsumeBrace();
739 SkipUntil(tok::r_brace, true);
740 return 0;
741 }
742
743 return ParseCXXInlineMethodDef(AS, DeclaratorInfo);
744 }
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000745 }
746
747 // member-declarator-list:
748 // member-declarator
749 // member-declarator-list ',' member-declarator
750
751 DeclTy *LastDeclInGroup = 0;
Sebastian Redl62261042008-12-09 20:22:58 +0000752 OwningExprResult BitfieldSize(Actions);
753 OwningExprResult Init(Actions);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000754
755 while (1) {
756
757 // member-declarator:
758 // declarator pure-specifier[opt]
759 // declarator constant-initializer[opt]
760 // identifier[opt] ':' constant-expression
761
762 if (Tok.is(tok::colon)) {
763 ConsumeToken();
Sebastian Redlbb4dae72008-12-09 13:15:23 +0000764 BitfieldSize = ParseConstantExpression();
765 if (BitfieldSize.isInvalid())
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000766 SkipUntil(tok::comma, true, true);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000767 }
768
769 // pure-specifier:
770 // '= 0'
771 //
772 // constant-initializer:
773 // '=' constant-expression
774
775 if (Tok.is(tok::equal)) {
776 ConsumeToken();
Sebastian Redlbb4dae72008-12-09 13:15:23 +0000777 Init = ParseInitializer();
778 if (Init.isInvalid())
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000779 SkipUntil(tok::comma, true, true);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000780 }
781
782 // If attributes exist after the declarator, parse them.
Sebastian Redl0c986032009-02-09 18:23:29 +0000783 if (Tok.is(tok::kw___attribute)) {
784 SourceLocation Loc;
785 AttributeList *AttrList = ParseAttributes(&Loc);
786 DeclaratorInfo.AddAttributes(AttrList, Loc);
787 }
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000788
Argiris Kirtzidis38f16712008-07-01 10:37:29 +0000789 // NOTE: If Sema is the Action module and declarator is an instance field,
790 // this call will *not* return the created decl; LastDeclInGroup will be
791 // returned instead.
792 // See Sema::ActOnCXXMemberDeclarator for details.
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000793 LastDeclInGroup = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
794 DeclaratorInfo,
Sebastian Redl6f1ee232008-12-10 00:02:53 +0000795 BitfieldSize.release(),
796 Init.release(),
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000797 LastDeclInGroup);
798
Douglas Gregor605de8d2008-12-16 21:30:33 +0000799 if (DeclaratorInfo.isFunctionDeclarator() &&
800 DeclaratorInfo.getDeclSpec().getStorageClassSpec()
801 != DeclSpec::SCS_typedef) {
802 // We just declared a member function. If this member function
803 // has any default arguments, we'll need to parse them later.
804 LateParsedMethodDeclaration *LateMethod = 0;
805 DeclaratorChunk::FunctionTypeInfo &FTI
806 = DeclaratorInfo.getTypeObject(0).Fun;
807 for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
808 if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
809 if (!LateMethod) {
810 // Push this method onto the stack of late-parsed method
811 // declarations.
812 getCurTopClassStack().MethodDecls.push_back(
813 LateParsedMethodDeclaration(LastDeclInGroup));
814 LateMethod = &getCurTopClassStack().MethodDecls.back();
815
816 // Add all of the parameters prior to this one (they don't
817 // have default arguments).
818 LateMethod->DefaultArgs.reserve(FTI.NumArgs);
819 for (unsigned I = 0; I < ParamIdx; ++I)
820 LateMethod->DefaultArgs.push_back(
821 LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param));
822 }
823
824 // Add this parameter to the list of parameters (it or may
825 // not have a default argument).
826 LateMethod->DefaultArgs.push_back(
827 LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
828 FTI.ArgInfo[ParamIdx].DefaultArgTokens));
829 }
830 }
831 }
832
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000833 // If we don't have a comma, it is either the end of the list (a ';')
834 // or an error, bail out.
835 if (Tok.isNot(tok::comma))
836 break;
837
838 // Consume the comma.
839 ConsumeToken();
840
841 // Parse the next declarator.
842 DeclaratorInfo.clear();
Sebastian Redl62261042008-12-09 20:22:58 +0000843 BitfieldSize = 0;
844 Init = 0;
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000845
846 // Attributes are only allowed on the second declarator.
Sebastian Redl0c986032009-02-09 18:23:29 +0000847 if (Tok.is(tok::kw___attribute)) {
848 SourceLocation Loc;
849 AttributeList *AttrList = ParseAttributes(&Loc);
850 DeclaratorInfo.AddAttributes(AttrList, Loc);
851 }
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000852
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000853 if (Tok.isNot(tok::colon))
854 ParseDeclarator(DeclaratorInfo);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000855 }
856
857 if (Tok.is(tok::semi)) {
858 ConsumeToken();
859 // Reverse the chain list.
860 return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
861 }
862
863 Diag(Tok, diag::err_expected_semi_decl_list);
864 // Skip to end of block or statement
865 SkipUntil(tok::r_brace, true, true);
866 if (Tok.is(tok::semi))
867 ConsumeToken();
868 return 0;
869}
870
871/// ParseCXXMemberSpecification - Parse the class definition.
872///
873/// member-specification:
874/// member-declaration member-specification[opt]
875/// access-specifier ':' member-specification[opt]
876///
877void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
878 unsigned TagType, DeclTy *TagDecl) {
Sanjiv Guptafa451432008-10-31 09:52:39 +0000879 assert((TagType == DeclSpec::TST_struct ||
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000880 TagType == DeclSpec::TST_union ||
Sanjiv Guptafa451432008-10-31 09:52:39 +0000881 TagType == DeclSpec::TST_class) && "Invalid TagType!");
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000882
Chris Lattnerc309ade2009-03-05 08:00:35 +0000883 PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
884 PP.getSourceManager(),
885 "parsing struct/union/class body");
Chris Lattner7efd75e2009-03-05 02:25:03 +0000886
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000887 SourceLocation LBraceLoc = ConsumeBrace();
888
Douglas Gregorcab994d2009-01-09 22:42:13 +0000889 if (!CurScope->isClassScope() && // Not about to define a nested class.
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000890 CurScope->isInCXXInlineMethodScope()) {
891 // We will define a local class of an inline method.
892 // Push a new LexedMethodsForTopClass for its inline methods.
893 PushTopClassStack();
894 }
895
896 // Enter a scope for the class.
Douglas Gregorcab994d2009-01-09 22:42:13 +0000897 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000898
Douglas Gregord406b032009-02-06 22:42:48 +0000899 if (TagDecl)
900 Actions.ActOnTagStartDefinition(CurScope, TagDecl);
901 else {
902 SkipUntil(tok::r_brace, false, false);
903 return;
904 }
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000905
906 // C++ 11p3: Members of a class defined with the keyword class are private
907 // by default. Members of a class defined with the keywords struct or union
908 // are public by default.
909 AccessSpecifier CurAS;
910 if (TagType == DeclSpec::TST_class)
911 CurAS = AS_private;
912 else
913 CurAS = AS_public;
914
915 // While we still have something to read, read the member-declarations.
916 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
917 // Each iteration of this loop reads one member-declaration.
918
919 // Check for extraneous top-level semicolon.
920 if (Tok.is(tok::semi)) {
921 Diag(Tok, diag::ext_extra_struct_semi);
922 ConsumeToken();
923 continue;
924 }
925
926 AccessSpecifier AS = getAccessSpecifierIfPresent();
927 if (AS != AS_none) {
928 // Current token is a C++ access specifier.
929 CurAS = AS;
930 ConsumeToken();
931 ExpectAndConsume(tok::colon, diag::err_expected_colon);
932 continue;
933 }
934
935 // Parse all the comma separated declarators.
936 ParseCXXClassMemberDeclaration(CurAS);
937 }
938
939 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
940
941 AttributeList *AttrList = 0;
942 // If attributes exist after class contents, parse them.
943 if (Tok.is(tok::kw___attribute))
944 AttrList = ParseAttributes(); // FIXME: where should I put them?
945
946 Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl,
947 LBraceLoc, RBraceLoc);
948
949 // C++ 9.2p2: Within the class member-specification, the class is regarded as
950 // complete within function bodies, default arguments,
951 // exception-specifications, and constructor ctor-initializers (including
952 // such things in nested classes).
953 //
Douglas Gregor605de8d2008-12-16 21:30:33 +0000954 // FIXME: Only function bodies and constructor ctor-initializers are
955 // parsed correctly, fix the rest.
Douglas Gregorcab994d2009-01-09 22:42:13 +0000956 if (!CurScope->getParent()->isClassScope()) {
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000957 // We are not inside a nested class. This class and its nested classes
Douglas Gregor605de8d2008-12-16 21:30:33 +0000958 // are complete and we can parse the delayed portions of method
959 // declarations and the lexed inline method definitions.
960 ParseLexedMethodDeclarations();
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000961 ParseLexedMethodDefs();
962
963 // For a local class of inline method, pop the LexedMethodsForTopClass that
964 // was previously pushed.
965
Sanjiv Guptafa451432008-10-31 09:52:39 +0000966 assert((CurScope->isInCXXInlineMethodScope() ||
967 TopClassStacks.size() == 1) &&
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000968 "MethodLexers not getting popped properly!");
969 if (CurScope->isInCXXInlineMethodScope())
970 PopTopClassStack();
971 }
972
973 // Leave the class scope.
Douglas Gregor95d40792008-12-10 06:34:36 +0000974 ClassScope.Exit();
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000975
Douglas Gregordb568cf2009-01-08 20:45:30 +0000976 Actions.ActOnTagFinishDefinition(CurScope, TagDecl);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000977}
Douglas Gregora65e8dd2008-11-05 04:29:56 +0000978
979/// ParseConstructorInitializer - Parse a C++ constructor initializer,
980/// which explicitly initializes the members or base classes of a
981/// class (C++ [class.base.init]). For example, the three initializers
982/// after the ':' in the Derived constructor below:
983///
984/// @code
985/// class Base { };
986/// class Derived : Base {
987/// int x;
988/// float f;
989/// public:
990/// Derived(float f) : Base(), x(17), f(f) { }
991/// };
992/// @endcode
993///
994/// [C++] ctor-initializer:
995/// ':' mem-initializer-list
996///
997/// [C++] mem-initializer-list:
998/// mem-initializer
999/// mem-initializer , mem-initializer-list
1000void Parser::ParseConstructorInitializer(DeclTy *ConstructorDecl) {
1001 assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
1002
1003 SourceLocation ColonLoc = ConsumeToken();
1004
1005 llvm::SmallVector<MemInitTy*, 4> MemInitializers;
1006
1007 do {
1008 MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
Douglas Gregor10a18fc2009-01-26 22:44:13 +00001009 if (!MemInit.isInvalid())
1010 MemInitializers.push_back(MemInit.get());
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001011
1012 if (Tok.is(tok::comma))
1013 ConsumeToken();
1014 else if (Tok.is(tok::l_brace))
1015 break;
1016 else {
1017 // Skip over garbage, until we get to '{'. Don't eat the '{'.
1018 SkipUntil(tok::l_brace, true, true);
1019 break;
1020 }
1021 } while (true);
1022
1023 Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc,
1024 &MemInitializers[0], MemInitializers.size());
1025}
1026
1027/// ParseMemInitializer - Parse a C++ member initializer, which is
1028/// part of a constructor initializer that explicitly initializes one
1029/// member or base class (C++ [class.base.init]). See
1030/// ParseConstructorInitializer for an example.
1031///
1032/// [C++] mem-initializer:
1033/// mem-initializer-id '(' expression-list[opt] ')'
1034///
1035/// [C++] mem-initializer-id:
1036/// '::'[opt] nested-name-specifier[opt] class-name
1037/// identifier
1038Parser::MemInitResult Parser::ParseMemInitializer(DeclTy *ConstructorDecl) {
1039 // FIXME: parse '::'[opt] nested-name-specifier[opt]
1040
1041 if (Tok.isNot(tok::identifier)) {
Chris Lattnerf006a222008-11-18 07:48:38 +00001042 Diag(Tok, diag::err_expected_member_or_base_name);
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001043 return true;
1044 }
1045
1046 // Get the identifier. This may be a member name or a class name,
1047 // but we'll let the semantic analysis determine which it is.
1048 IdentifierInfo *II = Tok.getIdentifierInfo();
1049 SourceLocation IdLoc = ConsumeToken();
1050
1051 // Parse the '('.
1052 if (Tok.isNot(tok::l_paren)) {
Chris Lattnerf006a222008-11-18 07:48:38 +00001053 Diag(Tok, diag::err_expected_lparen);
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001054 return true;
1055 }
1056 SourceLocation LParenLoc = ConsumeParen();
1057
1058 // Parse the optional expression-list.
Sebastian Redl6008ac32008-11-25 22:21:31 +00001059 ExprVector ArgExprs(Actions);
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001060 CommaLocsTy CommaLocs;
1061 if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
1062 SkipUntil(tok::r_paren);
1063 return true;
1064 }
1065
1066 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1067
Sebastian Redl6008ac32008-11-25 22:21:31 +00001068 return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, II, IdLoc,
1069 LParenLoc, ArgExprs.take(),
1070 ArgExprs.size(), &CommaLocs[0], RParenLoc);
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001071}
Douglas Gregor90a2c972008-11-25 03:22:00 +00001072
1073/// ParseExceptionSpecification - Parse a C++ exception-specification
1074/// (C++ [except.spec]).
1075///
Douglas Gregor9ed9ac82008-12-01 18:00:20 +00001076/// exception-specification:
1077/// 'throw' '(' type-id-list [opt] ')'
1078/// [MS] 'throw' '(' '...' ')'
Douglas Gregor90a2c972008-11-25 03:22:00 +00001079///
Douglas Gregor9ed9ac82008-12-01 18:00:20 +00001080/// type-id-list:
1081/// type-id
1082/// type-id-list ',' type-id
Douglas Gregor90a2c972008-11-25 03:22:00 +00001083///
Sebastian Redl0c986032009-02-09 18:23:29 +00001084bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc) {
Douglas Gregor90a2c972008-11-25 03:22:00 +00001085 assert(Tok.is(tok::kw_throw) && "expected throw");
1086
1087 SourceLocation ThrowLoc = ConsumeToken();
1088
1089 if (!Tok.is(tok::l_paren)) {
1090 return Diag(Tok, diag::err_expected_lparen_after) << "throw";
1091 }
1092 SourceLocation LParenLoc = ConsumeParen();
1093
Douglas Gregor9ed9ac82008-12-01 18:00:20 +00001094 // Parse throw(...), a Microsoft extension that means "this function
1095 // can throw anything".
1096 if (Tok.is(tok::ellipsis)) {
1097 SourceLocation EllipsisLoc = ConsumeToken();
1098 if (!getLang().Microsoft)
1099 Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
Sebastian Redl0c986032009-02-09 18:23:29 +00001100 EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Douglas Gregor9ed9ac82008-12-01 18:00:20 +00001101 return false;
1102 }
1103
Douglas Gregor90a2c972008-11-25 03:22:00 +00001104 // Parse the sequence of type-ids.
1105 while (Tok.isNot(tok::r_paren)) {
1106 ParseTypeName();
1107 if (Tok.is(tok::comma))
1108 ConsumeToken();
1109 else
1110 break;
1111 }
1112
Sebastian Redl0c986032009-02-09 18:23:29 +00001113 EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Douglas Gregor90a2c972008-11-25 03:22:00 +00001114 return false;
1115}