blob: 229c1815f25aa241c57200554631d0dbd652e04d [file] [log] [blame]
Chris Lattner8f08cb72007-08-25 06:57:03 +00001//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-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 Lattner8f08cb72007-08-25 06:57:03 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the C++ Declaration portions of the Parser interfaces.
11//
12//===----------------------------------------------------------------------===//
13
Douglas Gregor1b7f8982008-04-14 00:13:42 +000014#include "clang/Parse/Parser.h"
Chris Lattner500d3292009-01-29 05:15:15 +000015#include "clang/Parse/ParseDiagnostic.h"
Douglas Gregore37ac4f2008-04-13 21:30:24 +000016#include "clang/Parse/DeclSpec.h"
Chris Lattner8f08cb72007-08-25 06:57:03 +000017#include "clang/Parse/Scope.h"
Sebastian Redla55e52c2008-11-25 22:21:31 +000018#include "AstGuard.h"
Chris Lattnerbc8d5642008-12-18 01:12:00 +000019#include "ExtensionRAIIObject.h"
Chris Lattner8f08cb72007-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 Lattner04d66662007-10-09 17:33:22 +000046 assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
Chris Lattner8f08cb72007-08-25 06:57:03 +000047 SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'.
48
49 SourceLocation IdentLoc;
50 IdentifierInfo *Ident = 0;
51
Chris Lattner04d66662007-10-09 17:33:22 +000052 if (Tok.is(tok::identifier)) {
Chris Lattner8f08cb72007-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 Lattner04d66662007-10-09 17:33:22 +000059 if (Tok.is(tok::kw___attribute))
Chris Lattner8f08cb72007-08-25 06:57:03 +000060 // FIXME: save these somewhere.
61 AttrList = ParseAttributes();
62
Anders Carlssonf67606a2009-03-28 04:07:16 +000063 if (Tok.is(tok::equal))
Chris Lattner8f08cb72007-08-25 06:57:03 +000064 // FIXME: Verify no attributes were present.
Anders Carlssonf67606a2009-03-28 04:07:16 +000065 return ParseNamespaceAlias(IdentLoc, Ident);
66
67 if (Tok.is(tok::l_brace)) {
Chris Lattner8f08cb72007-08-25 06:57:03 +000068 SourceLocation LBrace = ConsumeBrace();
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +000069
70 // Enter a scope for the namespace.
Douglas Gregor8935b8b2008-12-10 06:34:36 +000071 ParseScope NamespaceScope(this, Scope::DeclScope);
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +000072
73 DeclTy *NamespcDecl =
74 Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace);
75
Chris Lattner49f28ca2009-03-05 08:00:35 +000076 PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions,
77 PP.getSourceManager(),
78 "parsing namespace");
Chris Lattner2254a9f2009-03-05 02:09:07 +000079
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +000080 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof))
Chris Lattnerbae35112007-08-25 18:15:16 +000081 ParseExternalDeclaration();
Chris Lattner8f08cb72007-08-25 06:57:03 +000082
Argyrios Kyrtzidis8ba5d792008-05-01 21:44:34 +000083 // Leave the namespace scope.
Douglas Gregor8935b8b2008-12-10 06:34:36 +000084 NamespaceScope.Exit();
Argyrios Kyrtzidis8ba5d792008-05-01 21:44:34 +000085
Chris Lattner8f08cb72007-08-25 06:57:03 +000086 SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +000087 Actions.ActOnFinishNamespaceDef(NamespcDecl, RBrace);
88
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +000089 return NamespcDecl;
Chris Lattner8f08cb72007-08-25 06:57:03 +000090
Chris Lattner8f08cb72007-08-25 06:57:03 +000091 } else {
Chris Lattner1ab3b962008-11-18 07:48:38 +000092 Diag(Tok, Ident ? diag::err_expected_lbrace :
93 diag::err_expected_ident_lbrace);
Chris Lattner8f08cb72007-08-25 06:57:03 +000094 }
95
96 return 0;
97}
Chris Lattnerc6fdc342008-01-12 07:05:38 +000098
Anders Carlssonf67606a2009-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
127 return 0;
128}
129
Chris Lattnerc6fdc342008-01-12 07:05:38 +0000130/// ParseLinkage - We know that the current token is a string_literal
131/// and just before that, that extern was seen.
132///
133/// linkage-specification: [C++ 7.5p2: dcl.link]
134/// 'extern' string-literal '{' declaration-seq[opt] '}'
135/// 'extern' string-literal declaration
136///
137Parser::DeclTy *Parser::ParseLinkage(unsigned Context) {
Douglas Gregorc19923d2008-11-21 16:10:08 +0000138 assert(Tok.is(tok::string_literal) && "Not a string literal!");
Chris Lattnerc6fdc342008-01-12 07:05:38 +0000139 llvm::SmallVector<char, 8> LangBuffer;
140 // LangBuffer is guaranteed to be big enough.
141 LangBuffer.resize(Tok.getLength());
142 const char *LangBufPtr = &LangBuffer[0];
143 unsigned StrSize = PP.getSpelling(Tok, LangBufPtr);
144
145 SourceLocation Loc = ConsumeStringToken();
Chris Lattnerc6fdc342008-01-12 07:05:38 +0000146
Douglas Gregor074149e2009-01-05 19:45:36 +0000147 ParseScope LinkageScope(this, Scope::DeclScope);
148 DeclTy *LinkageSpec
149 = Actions.ActOnStartLinkageSpecification(CurScope,
150 /*FIXME: */SourceLocation(),
151 Loc, LangBufPtr, StrSize,
152 Tok.is(tok::l_brace)? Tok.getLocation()
153 : SourceLocation());
154
155 if (Tok.isNot(tok::l_brace)) {
156 ParseDeclarationOrFunctionDefinition();
157 return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec,
158 SourceLocation());
Douglas Gregorf44515a2008-12-16 22:23:02 +0000159 }
160
161 SourceLocation LBrace = ConsumeBrace();
Douglas Gregorf44515a2008-12-16 22:23:02 +0000162 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
Douglas Gregor074149e2009-01-05 19:45:36 +0000163 ParseExternalDeclaration();
Chris Lattnerc6fdc342008-01-12 07:05:38 +0000164 }
165
Douglas Gregorf44515a2008-12-16 22:23:02 +0000166 SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
Douglas Gregor074149e2009-01-05 19:45:36 +0000167 return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, RBrace);
Chris Lattnerc6fdc342008-01-12 07:05:38 +0000168}
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000169
Douglas Gregorf780abc2008-12-30 03:27:21 +0000170/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
171/// using-directive. Assumes that current token is 'using'.
Chris Lattner2f274772009-01-06 06:55:51 +0000172Parser::DeclTy *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context) {
Douglas Gregorf780abc2008-12-30 03:27:21 +0000173 assert(Tok.is(tok::kw_using) && "Not using token");
174
175 // Eat 'using'.
176 SourceLocation UsingLoc = ConsumeToken();
177
Chris Lattner2f274772009-01-06 06:55:51 +0000178 if (Tok.is(tok::kw_namespace))
Douglas Gregorf780abc2008-12-30 03:27:21 +0000179 // Next token after 'using' is 'namespace' so it must be using-directive
180 return ParseUsingDirective(Context, UsingLoc);
Chris Lattner2f274772009-01-06 06:55:51 +0000181
182 // Otherwise, it must be using-declaration.
183 return ParseUsingDeclaration(Context, UsingLoc);
Douglas Gregorf780abc2008-12-30 03:27:21 +0000184}
185
186/// ParseUsingDirective - Parse C++ using-directive, assumes
187/// that current token is 'namespace' and 'using' was already parsed.
188///
189/// using-directive: [C++ 7.3.p4: namespace.udir]
190/// 'using' 'namespace' ::[opt] nested-name-specifier[opt]
191/// namespace-name ;
192/// [GNU] using-directive:
193/// 'using' 'namespace' ::[opt] nested-name-specifier[opt]
194/// namespace-name attributes[opt] ;
195///
196Parser::DeclTy *Parser::ParseUsingDirective(unsigned Context,
197 SourceLocation UsingLoc) {
198 assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
199
200 // Eat 'namespace'.
201 SourceLocation NamespcLoc = ConsumeToken();
202
203 CXXScopeSpec SS;
204 // Parse (optional) nested-name-specifier.
Chris Lattner7a0ab5f2009-01-06 06:59:53 +0000205 ParseOptionalCXXScopeSpecifier(SS);
Douglas Gregorf780abc2008-12-30 03:27:21 +0000206
207 AttributeList *AttrList = 0;
208 IdentifierInfo *NamespcName = 0;
209 SourceLocation IdentLoc = SourceLocation();
210
211 // Parse namespace-name.
Chris Lattner823c44e2009-01-06 07:27:21 +0000212 if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
Douglas Gregorf780abc2008-12-30 03:27:21 +0000213 Diag(Tok, diag::err_expected_namespace_name);
214 // If there was invalid namespace name, skip to end of decl, and eat ';'.
215 SkipUntil(tok::semi);
216 // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
217 return 0;
218 }
Chris Lattner823c44e2009-01-06 07:27:21 +0000219
220 // Parse identifier.
221 NamespcName = Tok.getIdentifierInfo();
222 IdentLoc = ConsumeToken();
223
224 // Parse (optional) attributes (most likely GNU strong-using extension).
225 if (Tok.is(tok::kw___attribute))
226 AttrList = ParseAttributes();
227
228 // Eat ';'.
229 ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
230 AttrList ? "attributes list" : "namespace name", tok::semi);
Douglas Gregorf780abc2008-12-30 03:27:21 +0000231
232 return Actions.ActOnUsingDirective(CurScope, UsingLoc, NamespcLoc, SS,
Chris Lattner823c44e2009-01-06 07:27:21 +0000233 IdentLoc, NamespcName, AttrList);
Douglas Gregorf780abc2008-12-30 03:27:21 +0000234}
235
236/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that
237/// 'using' was already seen.
238///
239/// using-declaration: [C++ 7.3.p3: namespace.udecl]
240/// 'using' 'typename'[opt] ::[opt] nested-name-specifier
241/// unqualified-id [TODO]
242/// 'using' :: unqualified-id [TODO]
243///
244Parser::DeclTy *Parser::ParseUsingDeclaration(unsigned Context,
245 SourceLocation UsingLoc) {
246 assert(false && "Not implemented");
247 // FIXME: Implement parsing.
248 return 0;
249}
250
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000251/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
252///
253/// static_assert-declaration:
254/// static_assert ( constant-expression , string-literal ) ;
255///
256Parser::DeclTy *Parser::ParseStaticAssertDeclaration() {
257 assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
258 SourceLocation StaticAssertLoc = ConsumeToken();
259
260 if (Tok.isNot(tok::l_paren)) {
261 Diag(Tok, diag::err_expected_lparen);
262 return 0;
263 }
264
265 SourceLocation LParenLoc = ConsumeParen();
266
267 OwningExprResult AssertExpr(ParseConstantExpression());
268 if (AssertExpr.isInvalid()) {
269 SkipUntil(tok::semi);
270 return 0;
271 }
272
Anders Carlssonad5f9602009-03-13 23:29:20 +0000273 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000274 return 0;
Anders Carlssonad5f9602009-03-13 23:29:20 +0000275
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000276 if (Tok.isNot(tok::string_literal)) {
277 Diag(Tok, diag::err_expected_string_literal);
278 SkipUntil(tok::semi);
279 return 0;
280 }
281
282 OwningExprResult AssertMessage(ParseStringLiteralExpression());
283 if (AssertMessage.isInvalid())
284 return 0;
285
Anders Carlsson94b15fb2009-03-15 18:44:04 +0000286 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000287
288 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert);
289
Anders Carlssonad5f9602009-03-13 23:29:20 +0000290 return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, move(AssertExpr),
Anders Carlsson94b15fb2009-03-15 18:44:04 +0000291 move(AssertMessage));
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000292}
293
Douglas Gregor42a552f2008-11-05 20:51:48 +0000294/// ParseClassName - Parse a C++ class-name, which names a class. Note
295/// that we only check that the result names a type; semantic analysis
296/// will need to verify that the type names a class. The result is
Douglas Gregor7f43d672009-02-25 23:52:28 +0000297/// either a type or NULL, depending on whether a type name was
Douglas Gregor42a552f2008-11-05 20:51:48 +0000298/// found.
299///
300/// class-name: [C++ 9.1]
301/// identifier
Douglas Gregor7f43d672009-02-25 23:52:28 +0000302/// simple-template-id
Douglas Gregor42a552f2008-11-05 20:51:48 +0000303///
Douglas Gregor7f43d672009-02-25 23:52:28 +0000304Parser::TypeTy *Parser::ParseClassName(SourceLocation &EndLocation,
305 const CXXScopeSpec *SS) {
306 // Check whether we have a template-id that names a type.
307 if (Tok.is(tok::annot_template_id)) {
308 TemplateIdAnnotation *TemplateId
309 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
310 if (TemplateId->Kind == TNK_Class_template) {
311 if (AnnotateTemplateIdTokenAsType(SS))
312 return 0;
313
314 assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
315 TypeTy *Type = Tok.getAnnotationValue();
316 EndLocation = Tok.getAnnotationEndLoc();
317 ConsumeToken();
318 return Type;
319 }
320
321 // Fall through to produce an error below.
322 }
323
Douglas Gregor42a552f2008-11-05 20:51:48 +0000324 if (Tok.isNot(tok::identifier)) {
Chris Lattner1ab3b962008-11-18 07:48:38 +0000325 Diag(Tok, diag::err_expected_class_name);
Douglas Gregor42a552f2008-11-05 20:51:48 +0000326 return 0;
327 }
328
329 // We have an identifier; check whether it is actually a type.
Douglas Gregorb696ea32009-02-04 17:00:24 +0000330 TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(),
331 Tok.getLocation(), CurScope, SS);
Douglas Gregor42a552f2008-11-05 20:51:48 +0000332 if (!Type) {
Chris Lattner1ab3b962008-11-18 07:48:38 +0000333 Diag(Tok, diag::err_expected_class_name);
Douglas Gregor42a552f2008-11-05 20:51:48 +0000334 return 0;
335 }
336
337 // Consume the identifier.
Douglas Gregor7f43d672009-02-25 23:52:28 +0000338 EndLocation = ConsumeToken();
Douglas Gregor42a552f2008-11-05 20:51:48 +0000339 return Type;
340}
341
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000342/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
343/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
344/// until we reach the start of a definition or see a token that
345/// cannot start a definition.
346///
347/// class-specifier: [C++ class]
348/// class-head '{' member-specification[opt] '}'
349/// class-head '{' member-specification[opt] '}' attributes[opt]
350/// class-head:
351/// class-key identifier[opt] base-clause[opt]
352/// class-key nested-name-specifier identifier base-clause[opt]
353/// class-key nested-name-specifier[opt] simple-template-id
354/// base-clause[opt]
355/// [GNU] class-key attributes[opt] identifier[opt] base-clause[opt]
356/// [GNU] class-key attributes[opt] nested-name-specifier
357/// identifier base-clause[opt]
358/// [GNU] class-key attributes[opt] nested-name-specifier[opt]
359/// simple-template-id base-clause[opt]
360/// class-key:
361/// 'class'
362/// 'struct'
363/// 'union'
364///
365/// elaborated-type-specifier: [C++ dcl.type.elab]
366/// class-key ::[opt] nested-name-specifier[opt] identifier
367/// class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
368/// simple-template-id
369///
370/// Note that the C++ class-specifier and elaborated-type-specifier,
371/// together, subsume the C99 struct-or-union-specifier:
372///
373/// struct-or-union-specifier: [C99 6.7.2.1]
374/// struct-or-union identifier[opt] '{' struct-contents '}'
375/// struct-or-union identifier
376/// [GNU] struct-or-union attributes[opt] identifier[opt] '{' struct-contents
377/// '}' attributes[opt]
378/// [GNU] struct-or-union attributes[opt] identifier
379/// struct-or-union:
380/// 'struct'
381/// 'union'
Douglas Gregorc4b4e7b2008-12-24 02:52:09 +0000382void Parser::ParseClassSpecifier(DeclSpec &DS,
Douglas Gregor06c0fec2009-03-25 22:00:53 +0000383 TemplateParameterLists *TemplateParams,
384 AccessSpecifier AS) {
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000385 assert((Tok.is(tok::kw_class) ||
386 Tok.is(tok::kw_struct) ||
387 Tok.is(tok::kw_union)) &&
388 "Not a class specifier");
389 DeclSpec::TST TagType =
390 Tok.is(tok::kw_class) ? DeclSpec::TST_class :
391 Tok.is(tok::kw_struct) ? DeclSpec::TST_struct :
392 DeclSpec::TST_union;
393
394 SourceLocation StartLoc = ConsumeToken();
395
396 AttributeList *Attr = 0;
397 // If attributes exist after tag, parse them.
398 if (Tok.is(tok::kw___attribute))
399 Attr = ParseAttributes();
400
Steve Narofff59e17e2008-12-24 20:59:21 +0000401 // If declspecs exist after tag, parse them.
402 if (Tok.is(tok::kw___declspec) && PP.getLangOptions().Microsoft)
403 FuzzyParseMicrosoftDeclSpec();
404
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000405 // Parse the (optional) nested-name-specifier.
406 CXXScopeSpec SS;
Douglas Gregor39a8de12009-02-25 19:37:18 +0000407 if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS))
408 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000409 Diag(Tok, diag::err_expected_ident);
Douglas Gregorcc636682009-02-17 23:15:12 +0000410
411 // Parse the (optional) class name or simple-template-id.
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000412 IdentifierInfo *Name = 0;
413 SourceLocation NameLoc;
Douglas Gregor39a8de12009-02-25 19:37:18 +0000414 TemplateIdAnnotation *TemplateId = 0;
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000415 if (Tok.is(tok::identifier)) {
416 Name = Tok.getIdentifierInfo();
417 NameLoc = ConsumeToken();
Douglas Gregor39a8de12009-02-25 19:37:18 +0000418 } else if (Tok.is(tok::annot_template_id)) {
419 TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
420 NameLoc = ConsumeToken();
Douglas Gregorcc636682009-02-17 23:15:12 +0000421
Douglas Gregor39a8de12009-02-25 19:37:18 +0000422 if (TemplateId->Kind != TNK_Class_template) {
423 // The template-name in the simple-template-id refers to
424 // something other than a class template. Give an appropriate
425 // error message and skip to the ';'.
426 SourceRange Range(NameLoc);
427 if (SS.isNotEmpty())
428 Range.setBegin(SS.getBeginLoc());
Douglas Gregorcc636682009-02-17 23:15:12 +0000429
Douglas Gregor39a8de12009-02-25 19:37:18 +0000430 Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
431 << Name << static_cast<int>(TemplateId->Kind) << Range;
Douglas Gregorcc636682009-02-17 23:15:12 +0000432
Douglas Gregor39a8de12009-02-25 19:37:18 +0000433 DS.SetTypeSpecError();
434 SkipUntil(tok::semi, false, true);
435 TemplateId->Destroy();
436 return;
Douglas Gregorcc636682009-02-17 23:15:12 +0000437 }
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000438 }
439
440 // There are three options here. If we have 'struct foo;', then
441 // this is a forward declaration. If we have 'struct foo {...' or
Douglas Gregor39a8de12009-02-25 19:37:18 +0000442 // 'struct foo :...' then this is a definition. Otherwise we have
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000443 // something like 'struct foo xyz', a reference.
444 Action::TagKind TK;
445 if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon)))
446 TK = Action::TK_Definition;
447 else if (Tok.is(tok::semi))
448 TK = Action::TK_Declaration;
449 else
450 TK = Action::TK_Reference;
451
Douglas Gregor39a8de12009-02-25 19:37:18 +0000452 if (!Name && !TemplateId && TK != Action::TK_Definition) {
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000453 // We have a declaration or reference to an anonymous class.
Chris Lattner1ab3b962008-11-18 07:48:38 +0000454 Diag(StartLoc, diag::err_anon_type_definition)
455 << DeclSpec::getSpecifierName(TagType);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000456
457 // Skip the rest of this declarator, up until the comma or semicolon.
458 SkipUntil(tok::comma, true);
Douglas Gregor39a8de12009-02-25 19:37:18 +0000459
460 if (TemplateId)
461 TemplateId->Destroy();
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000462 return;
463 }
464
Douglas Gregorddc29e12009-02-06 22:42:48 +0000465 // Create the tag portion of the class or class template.
Douglas Gregor212e81c2009-03-25 00:13:59 +0000466 Action::DeclResult TagOrTempResult;
Douglas Gregor39a8de12009-02-25 19:37:18 +0000467 if (TemplateId && TK != Action::TK_Reference) {
Douglas Gregorcc636682009-02-17 23:15:12 +0000468 // Explicit specialization or class template partial
469 // specialization. Let semantic analysis decide.
Douglas Gregor39a8de12009-02-25 19:37:18 +0000470 ASTTemplateArgsPtr TemplateArgsPtr(Actions,
471 TemplateId->getTemplateArgs(),
472 TemplateId->getTemplateArgIsType(),
473 TemplateId->NumArgs);
Douglas Gregor212e81c2009-03-25 00:13:59 +0000474 TagOrTempResult
Douglas Gregorcc636682009-02-17 23:15:12 +0000475 = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TK,
Douglas Gregor39a8de12009-02-25 19:37:18 +0000476 StartLoc, SS,
477 TemplateId->Template,
478 TemplateId->TemplateNameLoc,
479 TemplateId->LAngleLoc,
480 TemplateArgsPtr,
481 TemplateId->getTemplateArgLocations(),
482 TemplateId->RAngleLoc,
483 Attr,
Douglas Gregorcc636682009-02-17 23:15:12 +0000484 Action::MultiTemplateParamsArg(Actions,
485 TemplateParams? &(*TemplateParams)[0] : 0,
486 TemplateParams? TemplateParams->size() : 0));
Douglas Gregor39a8de12009-02-25 19:37:18 +0000487 TemplateId->Destroy();
488 } else if (TemplateParams && TK != Action::TK_Reference)
Douglas Gregor212e81c2009-03-25 00:13:59 +0000489 TagOrTempResult = Actions.ActOnClassTemplate(CurScope, TagType, TK,
490 StartLoc, SS, Name, NameLoc,
491 Attr,
Douglas Gregorddc29e12009-02-06 22:42:48 +0000492 Action::MultiTemplateParamsArg(Actions,
493 &(*TemplateParams)[0],
Anders Carlsson5aeccdb2009-03-26 00:52:18 +0000494 TemplateParams->size()),
495 AS);
Douglas Gregorddc29e12009-02-06 22:42:48 +0000496 else
Douglas Gregor212e81c2009-03-25 00:13:59 +0000497 TagOrTempResult = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS, Name,
Douglas Gregor06c0fec2009-03-25 22:00:53 +0000498 NameLoc, Attr, AS);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000499
500 // Parse the optional base clause (C++ only).
Chris Lattner22bd9052009-02-16 22:07:16 +0000501 if (getLang().CPlusPlus && Tok.is(tok::colon))
Douglas Gregor212e81c2009-03-25 00:13:59 +0000502 ParseBaseClause(TagOrTempResult.get());
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000503
504 // If there is a body, parse it and inform the actions module.
505 if (Tok.is(tok::l_brace))
Argyrios Kyrtzidis07952322008-07-01 10:37:29 +0000506 if (getLang().CPlusPlus)
Douglas Gregor212e81c2009-03-25 00:13:59 +0000507 ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
Argyrios Kyrtzidis07952322008-07-01 10:37:29 +0000508 else
Douglas Gregor212e81c2009-03-25 00:13:59 +0000509 ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000510 else if (TK == Action::TK_Definition) {
511 // FIXME: Complain that we have a base-specifier list but no
512 // definition.
Chris Lattner1ab3b962008-11-18 07:48:38 +0000513 Diag(Tok, diag::err_expected_lbrace);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000514 }
515
516 const char *PrevSpec = 0;
Douglas Gregor212e81c2009-03-25 00:13:59 +0000517 if (TagOrTempResult.isInvalid())
Douglas Gregorddc29e12009-02-06 22:42:48 +0000518 DS.SetTypeSpecError();
Douglas Gregor212e81c2009-03-25 00:13:59 +0000519 else if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec,
520 TagOrTempResult.get()))
Chris Lattner1ab3b962008-11-18 07:48:38 +0000521 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000522}
523
524/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
525///
526/// base-clause : [C++ class.derived]
527/// ':' base-specifier-list
528/// base-specifier-list:
529/// base-specifier '...'[opt]
530/// base-specifier-list ',' base-specifier '...'[opt]
531void Parser::ParseBaseClause(DeclTy *ClassDecl)
532{
533 assert(Tok.is(tok::colon) && "Not a base clause");
534 ConsumeToken();
535
Douglas Gregorf8268ae2008-10-22 17:49:05 +0000536 // Build up an array of parsed base specifiers.
537 llvm::SmallVector<BaseTy *, 8> BaseInfo;
538
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000539 while (true) {
540 // Parse a base-specifier.
Douglas Gregorf8268ae2008-10-22 17:49:05 +0000541 BaseResult Result = ParseBaseSpecifier(ClassDecl);
Douglas Gregor5ac8aff2009-01-26 22:44:13 +0000542 if (Result.isInvalid()) {
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000543 // Skip the rest of this base specifier, up until the comma or
544 // opening brace.
Douglas Gregorf8268ae2008-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 Gregor5ac8aff2009-01-26 22:44:13 +0000548 BaseInfo.push_back(Result.get());
Douglas Gregore37ac4f2008-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 Gregorf8268ae2008-10-22 17:49:05 +0000558
559 // Attach the base specifiers
560 Actions.ActOnBaseSpecifiers(ClassDecl, &BaseInfo[0], BaseInfo.size());
Douglas Gregore37ac4f2008-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
Douglas Gregorf8268ae2008-10-22 17:49:05 +0000574Parser::BaseResult Parser::ParseBaseSpecifier(DeclTy *ClassDecl)
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000575{
576 bool IsVirtual = false;
577 SourceLocation StartLoc = Tok.getLocation();
578
579 // Parse the 'virtual' keyword.
580 if (Tok.is(tok::kw_virtual)) {
581 ConsumeToken();
582 IsVirtual = true;
583 }
584
585 // Parse an (optional) access specifier.
586 AccessSpecifier Access = getAccessSpecifierIfPresent();
587 if (Access)
588 ConsumeToken();
589
590 // Parse the 'virtual' keyword (again!), in case it came after the
591 // access specifier.
592 if (Tok.is(tok::kw_virtual)) {
593 SourceLocation VirtualLoc = ConsumeToken();
594 if (IsVirtual) {
595 // Complain about duplicate 'virtual'
Chris Lattner1ab3b962008-11-18 07:48:38 +0000596 Diag(VirtualLoc, diag::err_dup_virtual)
597 << SourceRange(VirtualLoc, VirtualLoc);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000598 }
599
600 IsVirtual = true;
601 }
602
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000603 // Parse optional '::' and optional nested-name-specifier.
604 CXXScopeSpec SS;
Chris Lattner7a0ab5f2009-01-06 06:59:53 +0000605 ParseOptionalCXXScopeSpecifier(SS);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000606
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000607 // The location of the base class itself.
608 SourceLocation BaseLoc = Tok.getLocation();
Douglas Gregor42a552f2008-11-05 20:51:48 +0000609
610 // Parse the class-name.
Douglas Gregor7f43d672009-02-25 23:52:28 +0000611 SourceLocation EndLocation;
612 TypeTy *BaseType = ParseClassName(EndLocation, &SS);
Douglas Gregor42a552f2008-11-05 20:51:48 +0000613 if (!BaseType)
614 return true;
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000615
616 // Find the complete source range for the base-specifier.
Douglas Gregor7f43d672009-02-25 23:52:28 +0000617 SourceRange Range(StartLoc, EndLocation);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000618
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000619 // Notify semantic analysis that we have parsed a complete
620 // base-specifier.
Sebastian Redla55e52c2008-11-25 22:21:31 +0000621 return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
622 BaseType, BaseLoc);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000623}
624
625/// getAccessSpecifierIfPresent - Determine whether the next token is
626/// a C++ access-specifier.
627///
628/// access-specifier: [C++ class.derived]
629/// 'private'
630/// 'protected'
631/// 'public'
Douglas Gregor1b7f8982008-04-14 00:13:42 +0000632AccessSpecifier Parser::getAccessSpecifierIfPresent() const
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000633{
634 switch (Tok.getKind()) {
635 default: return AS_none;
636 case tok::kw_private: return AS_private;
637 case tok::kw_protected: return AS_protected;
638 case tok::kw_public: return AS_public;
639 }
640}
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000641
642/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
643///
644/// member-declaration:
645/// decl-specifier-seq[opt] member-declarator-list[opt] ';'
646/// function-definition ';'[opt]
647/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
648/// using-declaration [TODO]
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000649/// [C++0x] static_assert-declaration
Anders Carlsson5aeccdb2009-03-26 00:52:18 +0000650/// template-declaration
Chris Lattnerbc8d5642008-12-18 01:12:00 +0000651/// [GNU] '__extension__' member-declaration
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000652///
653/// member-declarator-list:
654/// member-declarator
655/// member-declarator-list ',' member-declarator
656///
657/// member-declarator:
658/// declarator pure-specifier[opt]
659/// declarator constant-initializer[opt]
660/// identifier[opt] ':' constant-expression
661///
662/// pure-specifier: [TODO]
663/// '= 0'
664///
665/// constant-initializer:
666/// '=' constant-expression
667///
668Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000669 // static_assert-declaration
670 if (Tok.is(tok::kw_static_assert))
671 return ParseStaticAssertDeclaration();
672
Anders Carlsson5aeccdb2009-03-26 00:52:18 +0000673 if (Tok.is(tok::kw_template))
674 return ParseTemplateDeclarationOrSpecialization(Declarator::MemberContext,
675 AS);
676
Chris Lattnerbc8d5642008-12-18 01:12:00 +0000677 // Handle: member-declaration ::= '__extension__' member-declaration
678 if (Tok.is(tok::kw___extension__)) {
679 // __extension__ silences extension warnings in the subexpression.
680 ExtensionRAIIObject O(Diags); // Use RAII to do this.
681 ConsumeToken();
682 return ParseCXXClassMemberDeclaration(AS);
683 }
684
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000685 SourceLocation DSStart = Tok.getLocation();
686 // decl-specifier-seq:
687 // Parse the common declaration-specifiers piece.
688 DeclSpec DS;
Douglas Gregor06c0fec2009-03-25 22:00:53 +0000689 ParseDeclarationSpecifiers(DS, 0, AS);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000690
691 if (Tok.is(tok::semi)) {
692 ConsumeToken();
693 // C++ 9.2p7: The member-declarator-list can be omitted only after a
694 // class-specifier or an enum-specifier or in a friend declaration.
695 // FIXME: Friend declarations.
696 switch (DS.getTypeSpecType()) {
697 case DeclSpec::TST_struct:
698 case DeclSpec::TST_union:
699 case DeclSpec::TST_class:
700 case DeclSpec::TST_enum:
701 return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
702 default:
703 Diag(DSStart, diag::err_no_declarators);
704 return 0;
705 }
706 }
Argyrios Kyrtzidis07952322008-07-01 10:37:29 +0000707
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000708 Declarator DeclaratorInfo(DS, Declarator::MemberContext);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000709
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000710 if (Tok.isNot(tok::colon)) {
711 // Parse the first declarator.
712 ParseDeclarator(DeclaratorInfo);
713 // Error parsing the declarator?
Douglas Gregor10bd3682008-11-17 22:58:34 +0000714 if (!DeclaratorInfo.hasName()) {
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000715 // If so, skip until the semi-colon or a }.
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000716 SkipUntil(tok::r_brace, true);
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000717 if (Tok.is(tok::semi))
718 ConsumeToken();
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000719 return 0;
720 }
721
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000722 // function-definition:
Douglas Gregor7ad83902008-11-05 04:29:56 +0000723 if (Tok.is(tok::l_brace)
724 || (DeclaratorInfo.isFunctionDeclarator() && Tok.is(tok::colon))) {
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000725 if (!DeclaratorInfo.isFunctionDeclarator()) {
726 Diag(Tok, diag::err_func_def_no_params);
727 ConsumeBrace();
728 SkipUntil(tok::r_brace, true);
729 return 0;
730 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000731
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000732 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
733 Diag(Tok, diag::err_function_declared_typedef);
734 // This recovery skips the entire function body. It would be nice
735 // to simply call ParseCXXInlineMethodDef() below, however Sema
736 // assumes the declarator represents a function, not a typedef.
737 ConsumeBrace();
738 SkipUntil(tok::r_brace, true);
739 return 0;
740 }
741
742 return ParseCXXInlineMethodDef(AS, DeclaratorInfo);
743 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000744 }
745
746 // member-declarator-list:
747 // member-declarator
748 // member-declarator-list ',' member-declarator
749
750 DeclTy *LastDeclInGroup = 0;
Sebastian Redl15faa7f2008-12-09 20:22:58 +0000751 OwningExprResult BitfieldSize(Actions);
752 OwningExprResult Init(Actions);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000753
754 while (1) {
755
756 // member-declarator:
757 // declarator pure-specifier[opt]
758 // declarator constant-initializer[opt]
759 // identifier[opt] ':' constant-expression
760
761 if (Tok.is(tok::colon)) {
762 ConsumeToken();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000763 BitfieldSize = ParseConstantExpression();
764 if (BitfieldSize.isInvalid())
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000765 SkipUntil(tok::comma, true, true);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000766 }
767
768 // pure-specifier:
769 // '= 0'
770 //
771 // constant-initializer:
772 // '=' constant-expression
773
774 if (Tok.is(tok::equal)) {
775 ConsumeToken();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000776 Init = ParseInitializer();
777 if (Init.isInvalid())
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000778 SkipUntil(tok::comma, true, true);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000779 }
780
781 // If attributes exist after the declarator, parse them.
Sebastian Redlab197ba2009-02-09 18:23:29 +0000782 if (Tok.is(tok::kw___attribute)) {
783 SourceLocation Loc;
784 AttributeList *AttrList = ParseAttributes(&Loc);
785 DeclaratorInfo.AddAttributes(AttrList, Loc);
786 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000787
Argyrios Kyrtzidis07952322008-07-01 10:37:29 +0000788 // NOTE: If Sema is the Action module and declarator is an instance field,
789 // this call will *not* return the created decl; LastDeclInGroup will be
790 // returned instead.
791 // See Sema::ActOnCXXMemberDeclarator for details.
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000792 LastDeclInGroup = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
793 DeclaratorInfo,
Sebastian Redleffa8d12008-12-10 00:02:53 +0000794 BitfieldSize.release(),
795 Init.release(),
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000796 LastDeclInGroup);
797
Douglas Gregor72b505b2008-12-16 21:30:33 +0000798 if (DeclaratorInfo.isFunctionDeclarator() &&
799 DeclaratorInfo.getDeclSpec().getStorageClassSpec()
800 != DeclSpec::SCS_typedef) {
801 // We just declared a member function. If this member function
802 // has any default arguments, we'll need to parse them later.
803 LateParsedMethodDeclaration *LateMethod = 0;
804 DeclaratorChunk::FunctionTypeInfo &FTI
805 = DeclaratorInfo.getTypeObject(0).Fun;
806 for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
807 if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
808 if (!LateMethod) {
809 // Push this method onto the stack of late-parsed method
810 // declarations.
811 getCurTopClassStack().MethodDecls.push_back(
812 LateParsedMethodDeclaration(LastDeclInGroup));
813 LateMethod = &getCurTopClassStack().MethodDecls.back();
814
815 // Add all of the parameters prior to this one (they don't
816 // have default arguments).
817 LateMethod->DefaultArgs.reserve(FTI.NumArgs);
818 for (unsigned I = 0; I < ParamIdx; ++I)
819 LateMethod->DefaultArgs.push_back(
820 LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param));
821 }
822
823 // Add this parameter to the list of parameters (it or may
824 // not have a default argument).
825 LateMethod->DefaultArgs.push_back(
826 LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
827 FTI.ArgInfo[ParamIdx].DefaultArgTokens));
828 }
829 }
830 }
831
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000832 // If we don't have a comma, it is either the end of the list (a ';')
833 // or an error, bail out.
834 if (Tok.isNot(tok::comma))
835 break;
836
837 // Consume the comma.
838 ConsumeToken();
839
840 // Parse the next declarator.
841 DeclaratorInfo.clear();
Sebastian Redl15faa7f2008-12-09 20:22:58 +0000842 BitfieldSize = 0;
843 Init = 0;
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000844
845 // Attributes are only allowed on the second declarator.
Sebastian Redlab197ba2009-02-09 18:23:29 +0000846 if (Tok.is(tok::kw___attribute)) {
847 SourceLocation Loc;
848 AttributeList *AttrList = ParseAttributes(&Loc);
849 DeclaratorInfo.AddAttributes(AttrList, Loc);
850 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000851
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000852 if (Tok.isNot(tok::colon))
853 ParseDeclarator(DeclaratorInfo);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000854 }
855
856 if (Tok.is(tok::semi)) {
857 ConsumeToken();
858 // Reverse the chain list.
859 return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
860 }
861
862 Diag(Tok, diag::err_expected_semi_decl_list);
863 // Skip to end of block or statement
864 SkipUntil(tok::r_brace, true, true);
865 if (Tok.is(tok::semi))
866 ConsumeToken();
867 return 0;
868}
869
870/// ParseCXXMemberSpecification - Parse the class definition.
871///
872/// member-specification:
873/// member-declaration member-specification[opt]
874/// access-specifier ':' member-specification[opt]
875///
876void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
877 unsigned TagType, DeclTy *TagDecl) {
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000878 assert((TagType == DeclSpec::TST_struct ||
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000879 TagType == DeclSpec::TST_union ||
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000880 TagType == DeclSpec::TST_class) && "Invalid TagType!");
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000881
Chris Lattner49f28ca2009-03-05 08:00:35 +0000882 PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
883 PP.getSourceManager(),
884 "parsing struct/union/class body");
Chris Lattner27b7f102009-03-05 02:25:03 +0000885
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000886 SourceLocation LBraceLoc = ConsumeBrace();
887
Douglas Gregor3218c4b2009-01-09 22:42:13 +0000888 if (!CurScope->isClassScope() && // Not about to define a nested class.
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000889 CurScope->isInCXXInlineMethodScope()) {
890 // We will define a local class of an inline method.
891 // Push a new LexedMethodsForTopClass for its inline methods.
892 PushTopClassStack();
893 }
894
895 // Enter a scope for the class.
Douglas Gregor3218c4b2009-01-09 22:42:13 +0000896 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000897
Douglas Gregorddc29e12009-02-06 22:42:48 +0000898 if (TagDecl)
899 Actions.ActOnTagStartDefinition(CurScope, TagDecl);
900 else {
901 SkipUntil(tok::r_brace, false, false);
902 return;
903 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000904
905 // C++ 11p3: Members of a class defined with the keyword class are private
906 // by default. Members of a class defined with the keywords struct or union
907 // are public by default.
908 AccessSpecifier CurAS;
909 if (TagType == DeclSpec::TST_class)
910 CurAS = AS_private;
911 else
912 CurAS = AS_public;
913
914 // While we still have something to read, read the member-declarations.
915 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
916 // Each iteration of this loop reads one member-declaration.
917
918 // Check for extraneous top-level semicolon.
919 if (Tok.is(tok::semi)) {
920 Diag(Tok, diag::ext_extra_struct_semi);
921 ConsumeToken();
922 continue;
923 }
924
925 AccessSpecifier AS = getAccessSpecifierIfPresent();
926 if (AS != AS_none) {
927 // Current token is a C++ access specifier.
928 CurAS = AS;
929 ConsumeToken();
930 ExpectAndConsume(tok::colon, diag::err_expected_colon);
931 continue;
932 }
933
934 // Parse all the comma separated declarators.
935 ParseCXXClassMemberDeclaration(CurAS);
936 }
937
938 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
939
940 AttributeList *AttrList = 0;
941 // If attributes exist after class contents, parse them.
942 if (Tok.is(tok::kw___attribute))
943 AttrList = ParseAttributes(); // FIXME: where should I put them?
944
945 Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl,
946 LBraceLoc, RBraceLoc);
947
948 // C++ 9.2p2: Within the class member-specification, the class is regarded as
949 // complete within function bodies, default arguments,
950 // exception-specifications, and constructor ctor-initializers (including
951 // such things in nested classes).
952 //
Douglas Gregor72b505b2008-12-16 21:30:33 +0000953 // FIXME: Only function bodies and constructor ctor-initializers are
954 // parsed correctly, fix the rest.
Douglas Gregor3218c4b2009-01-09 22:42:13 +0000955 if (!CurScope->getParent()->isClassScope()) {
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000956 // We are not inside a nested class. This class and its nested classes
Douglas Gregor72b505b2008-12-16 21:30:33 +0000957 // are complete and we can parse the delayed portions of method
958 // declarations and the lexed inline method definitions.
959 ParseLexedMethodDeclarations();
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000960 ParseLexedMethodDefs();
961
962 // For a local class of inline method, pop the LexedMethodsForTopClass that
963 // was previously pushed.
964
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000965 assert((CurScope->isInCXXInlineMethodScope() ||
966 TopClassStacks.size() == 1) &&
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000967 "MethodLexers not getting popped properly!");
968 if (CurScope->isInCXXInlineMethodScope())
969 PopTopClassStack();
970 }
971
972 // Leave the class scope.
Douglas Gregor8935b8b2008-12-10 06:34:36 +0000973 ClassScope.Exit();
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000974
Douglas Gregor72de6672009-01-08 20:45:30 +0000975 Actions.ActOnTagFinishDefinition(CurScope, TagDecl);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000976}
Douglas Gregor7ad83902008-11-05 04:29:56 +0000977
978/// ParseConstructorInitializer - Parse a C++ constructor initializer,
979/// which explicitly initializes the members or base classes of a
980/// class (C++ [class.base.init]). For example, the three initializers
981/// after the ':' in the Derived constructor below:
982///
983/// @code
984/// class Base { };
985/// class Derived : Base {
986/// int x;
987/// float f;
988/// public:
989/// Derived(float f) : Base(), x(17), f(f) { }
990/// };
991/// @endcode
992///
993/// [C++] ctor-initializer:
994/// ':' mem-initializer-list
995///
996/// [C++] mem-initializer-list:
997/// mem-initializer
998/// mem-initializer , mem-initializer-list
999void Parser::ParseConstructorInitializer(DeclTy *ConstructorDecl) {
1000 assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
1001
1002 SourceLocation ColonLoc = ConsumeToken();
1003
1004 llvm::SmallVector<MemInitTy*, 4> MemInitializers;
1005
1006 do {
1007 MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
Douglas Gregor5ac8aff2009-01-26 22:44:13 +00001008 if (!MemInit.isInvalid())
1009 MemInitializers.push_back(MemInit.get());
Douglas Gregor7ad83902008-11-05 04:29:56 +00001010
1011 if (Tok.is(tok::comma))
1012 ConsumeToken();
1013 else if (Tok.is(tok::l_brace))
1014 break;
1015 else {
1016 // Skip over garbage, until we get to '{'. Don't eat the '{'.
1017 SkipUntil(tok::l_brace, true, true);
1018 break;
1019 }
1020 } while (true);
1021
1022 Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc,
1023 &MemInitializers[0], MemInitializers.size());
1024}
1025
1026/// ParseMemInitializer - Parse a C++ member initializer, which is
1027/// part of a constructor initializer that explicitly initializes one
1028/// member or base class (C++ [class.base.init]). See
1029/// ParseConstructorInitializer for an example.
1030///
1031/// [C++] mem-initializer:
1032/// mem-initializer-id '(' expression-list[opt] ')'
1033///
1034/// [C++] mem-initializer-id:
1035/// '::'[opt] nested-name-specifier[opt] class-name
1036/// identifier
1037Parser::MemInitResult Parser::ParseMemInitializer(DeclTy *ConstructorDecl) {
1038 // FIXME: parse '::'[opt] nested-name-specifier[opt]
1039
1040 if (Tok.isNot(tok::identifier)) {
Chris Lattner1ab3b962008-11-18 07:48:38 +00001041 Diag(Tok, diag::err_expected_member_or_base_name);
Douglas Gregor7ad83902008-11-05 04:29:56 +00001042 return true;
1043 }
1044
1045 // Get the identifier. This may be a member name or a class name,
1046 // but we'll let the semantic analysis determine which it is.
1047 IdentifierInfo *II = Tok.getIdentifierInfo();
1048 SourceLocation IdLoc = ConsumeToken();
1049
1050 // Parse the '('.
1051 if (Tok.isNot(tok::l_paren)) {
Chris Lattner1ab3b962008-11-18 07:48:38 +00001052 Diag(Tok, diag::err_expected_lparen);
Douglas Gregor7ad83902008-11-05 04:29:56 +00001053 return true;
1054 }
1055 SourceLocation LParenLoc = ConsumeParen();
1056
1057 // Parse the optional expression-list.
Sebastian Redla55e52c2008-11-25 22:21:31 +00001058 ExprVector ArgExprs(Actions);
Douglas Gregor7ad83902008-11-05 04:29:56 +00001059 CommaLocsTy CommaLocs;
1060 if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
1061 SkipUntil(tok::r_paren);
1062 return true;
1063 }
1064
1065 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1066
Sebastian Redla55e52c2008-11-25 22:21:31 +00001067 return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, II, IdLoc,
1068 LParenLoc, ArgExprs.take(),
1069 ArgExprs.size(), &CommaLocs[0], RParenLoc);
Douglas Gregor7ad83902008-11-05 04:29:56 +00001070}
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001071
1072/// ParseExceptionSpecification - Parse a C++ exception-specification
1073/// (C++ [except.spec]).
1074///
Douglas Gregora4745612008-12-01 18:00:20 +00001075/// exception-specification:
1076/// 'throw' '(' type-id-list [opt] ')'
1077/// [MS] 'throw' '(' '...' ')'
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001078///
Douglas Gregora4745612008-12-01 18:00:20 +00001079/// type-id-list:
1080/// type-id
1081/// type-id-list ',' type-id
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001082///
Sebastian Redlab197ba2009-02-09 18:23:29 +00001083bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc) {
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001084 assert(Tok.is(tok::kw_throw) && "expected throw");
1085
1086 SourceLocation ThrowLoc = ConsumeToken();
1087
1088 if (!Tok.is(tok::l_paren)) {
1089 return Diag(Tok, diag::err_expected_lparen_after) << "throw";
1090 }
1091 SourceLocation LParenLoc = ConsumeParen();
1092
Douglas Gregora4745612008-12-01 18:00:20 +00001093 // Parse throw(...), a Microsoft extension that means "this function
1094 // can throw anything".
1095 if (Tok.is(tok::ellipsis)) {
1096 SourceLocation EllipsisLoc = ConsumeToken();
1097 if (!getLang().Microsoft)
1098 Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
Sebastian Redlab197ba2009-02-09 18:23:29 +00001099 EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Douglas Gregora4745612008-12-01 18:00:20 +00001100 return false;
1101 }
1102
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001103 // Parse the sequence of type-ids.
1104 while (Tok.isNot(tok::r_paren)) {
1105 ParseTypeName();
1106 if (Tok.is(tok::comma))
1107 ConsumeToken();
1108 else
1109 break;
1110 }
1111
Sebastian Redlab197ba2009-02-09 18:23:29 +00001112 EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001113 return false;
1114}