blob: 4201e1cb1eb2aee62181f14c513d0ee324a37697 [file] [log] [blame]
Chris Lattnerf7b2e552007-08-25 06:57:03 +00001//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner959e5be2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattnerf7b2e552007-08-25 06:57:03 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the C++ Declaration portions of the Parser interfaces.
11//
12//===----------------------------------------------------------------------===//
13
Douglas Gregor696be932008-04-14 00:13:42 +000014#include "clang/Parse/Parser.h"
Chris Lattner545f39e2009-01-29 05:15:15 +000015#include "clang/Parse/ParseDiagnostic.h"
Douglas Gregorec93f442008-04-13 21:30:24 +000016#include "clang/Parse/DeclSpec.h"
Chris Lattnerf7b2e552007-08-25 06:57:03 +000017#include "clang/Parse/Scope.h"
Sebastian Redl6008ac32008-11-25 22:21:31 +000018#include "AstGuard.h"
Chris Lattnerf3375de2008-12-18 01:12:00 +000019#include "ExtensionRAIIObject.h"
Chris Lattnerf7b2e552007-08-25 06:57:03 +000020using namespace clang;
21
22/// ParseNamespace - We know that the current token is a namespace keyword. This
23/// may either be a top level namespace or a block-level namespace alias.
24///
25/// namespace-definition: [C++ 7.3: basic.namespace]
26/// named-namespace-definition
27/// unnamed-namespace-definition
28///
29/// unnamed-namespace-definition:
30/// 'namespace' attributes[opt] '{' namespace-body '}'
31///
32/// named-namespace-definition:
33/// original-namespace-definition
34/// extension-namespace-definition
35///
36/// original-namespace-definition:
37/// 'namespace' identifier attributes[opt] '{' namespace-body '}'
38///
39/// extension-namespace-definition:
40/// 'namespace' original-namespace-name '{' namespace-body '}'
41///
42/// namespace-alias-definition: [C++ 7.3.2: namespace.alias]
43/// 'namespace' identifier '=' qualified-namespace-specifier ';'
44///
Chris Lattner5261d0c2009-03-28 19:18:32 +000045Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context) {
Chris Lattner34a01ad2007-10-09 17:33:22 +000046 assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
Chris Lattnerf7b2e552007-08-25 06:57:03 +000047 SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'.
48
49 SourceLocation IdentLoc;
50 IdentifierInfo *Ident = 0;
51
Chris Lattner34a01ad2007-10-09 17:33:22 +000052 if (Tok.is(tok::identifier)) {
Chris Lattnerf7b2e552007-08-25 06:57:03 +000053 Ident = Tok.getIdentifierInfo();
54 IdentLoc = ConsumeToken(); // eat the identifier.
55 }
56
57 // Read label attributes, if present.
Chris Lattner5261d0c2009-03-28 19:18:32 +000058 Action::AttrTy *AttrList = 0;
Chris Lattner34a01ad2007-10-09 17:33:22 +000059 if (Tok.is(tok::kw___attribute))
Chris Lattnerf7b2e552007-08-25 06:57:03 +000060 // FIXME: save these somewhere.
61 AttrList = ParseAttributes();
62
Anders Carlssonf94cca22009-03-28 04:07:16 +000063 if (Tok.is(tok::equal))
Chris Lattnerf7b2e552007-08-25 06:57:03 +000064 // FIXME: Verify no attributes were present.
Anders Carlsson26de7882009-03-28 22:53:22 +000065 return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident);
Anders Carlssonf94cca22009-03-28 04:07:16 +000066
67 if (Tok.is(tok::l_brace)) {
Chris Lattnerf7b2e552007-08-25 06:57:03 +000068 SourceLocation LBrace = ConsumeBrace();
Argiris Kirtzidis03e6aaf2008-04-27 13:50:30 +000069
70 // Enter a scope for the namespace.
Douglas Gregor95d40792008-12-10 06:34:36 +000071 ParseScope NamespaceScope(this, Scope::DeclScope);
Argiris Kirtzidis03e6aaf2008-04-27 13:50:30 +000072
Chris Lattner5261d0c2009-03-28 19:18:32 +000073 DeclPtrTy NamespcDecl =
Argiris Kirtzidis03e6aaf2008-04-27 13:50:30 +000074 Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace);
75
Chris Lattnerc309ade2009-03-05 08:00:35 +000076 PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions,
77 PP.getSourceManager(),
78 "parsing namespace");
Chris Lattner696da202009-03-05 02:09:07 +000079
Argiris Kirtzidis03e6aaf2008-04-27 13:50:30 +000080 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof))
Chris Lattner9c135722007-08-25 18:15:16 +000081 ParseExternalDeclaration();
Chris Lattnerf7b2e552007-08-25 06:57:03 +000082
Argiris Kirtzidis5f21e592008-05-01 21:44:34 +000083 // Leave the namespace scope.
Douglas Gregor95d40792008-12-10 06:34:36 +000084 NamespaceScope.Exit();
Argiris Kirtzidis5f21e592008-05-01 21:44:34 +000085
Chris Lattnerf7b2e552007-08-25 06:57:03 +000086 SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
Argiris Kirtzidis03e6aaf2008-04-27 13:50:30 +000087 Actions.ActOnFinishNamespaceDef(NamespcDecl, RBrace);
88
Argiris Kirtzidis03e6aaf2008-04-27 13:50:30 +000089 return NamespcDecl;
Chris Lattnerf7b2e552007-08-25 06:57:03 +000090
Chris Lattnerf7b2e552007-08-25 06:57:03 +000091 } else {
Chris Lattnerf006a222008-11-18 07:48:38 +000092 Diag(Tok, Ident ? diag::err_expected_lbrace :
93 diag::err_expected_ident_lbrace);
Chris Lattnerf7b2e552007-08-25 06:57:03 +000094 }
95
Chris Lattner5261d0c2009-03-28 19:18:32 +000096 return DeclPtrTy();
Chris Lattnerf7b2e552007-08-25 06:57:03 +000097}
Chris Lattner806a5f52008-01-12 07:05:38 +000098
Anders Carlssonf94cca22009-03-28 04:07:16 +000099/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
100/// alias definition.
101///
Anders Carlsson26de7882009-03-28 22:53:22 +0000102Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
103 SourceLocation AliasLoc,
Chris Lattner5261d0c2009-03-28 19:18:32 +0000104 IdentifierInfo *Alias) {
Anders Carlssonf94cca22009-03-28 04:07:16 +0000105 assert(Tok.is(tok::equal) && "Not equal token");
106
107 ConsumeToken(); // eat the '='.
108
109 CXXScopeSpec SS;
110 // Parse (optional) nested-name-specifier.
111 ParseOptionalCXXScopeSpecifier(SS);
112
113 if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
114 Diag(Tok, diag::err_expected_namespace_name);
115 // Skip to end of the definition and eat the ';'.
116 SkipUntil(tok::semi);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000117 return DeclPtrTy();
Anders Carlssonf94cca22009-03-28 04:07:16 +0000118 }
119
120 // Parse identifier.
Anders Carlsson26de7882009-03-28 22:53:22 +0000121 IdentifierInfo *Ident = Tok.getIdentifierInfo();
122 SourceLocation IdentLoc = ConsumeToken();
Anders Carlssonf94cca22009-03-28 04:07:16 +0000123
124 // Eat the ';'.
125 ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
126 "namespace name", tok::semi);
127
Anders Carlsson26de7882009-03-28 22:53:22 +0000128 return Actions.ActOnNamespaceAliasDef(CurScope, NamespaceLoc, AliasLoc, Alias,
129 SS, IdentLoc, Ident);
Anders Carlssonf94cca22009-03-28 04:07:16 +0000130}
131
Chris Lattner806a5f52008-01-12 07:05:38 +0000132/// ParseLinkage - We know that the current token is a string_literal
133/// and just before that, that extern was seen.
134///
135/// linkage-specification: [C++ 7.5p2: dcl.link]
136/// 'extern' string-literal '{' declaration-seq[opt] '}'
137/// 'extern' string-literal declaration
138///
Chris Lattner5261d0c2009-03-28 19:18:32 +0000139Parser::DeclPtrTy Parser::ParseLinkage(unsigned Context) {
Douglas Gregor61818c52008-11-21 16:10:08 +0000140 assert(Tok.is(tok::string_literal) && "Not a string literal!");
Chris Lattner806a5f52008-01-12 07:05:38 +0000141 llvm::SmallVector<char, 8> LangBuffer;
142 // LangBuffer is guaranteed to be big enough.
143 LangBuffer.resize(Tok.getLength());
144 const char *LangBufPtr = &LangBuffer[0];
145 unsigned StrSize = PP.getSpelling(Tok, LangBufPtr);
146
147 SourceLocation Loc = ConsumeStringToken();
Chris Lattner806a5f52008-01-12 07:05:38 +0000148
Douglas Gregord8028382009-01-05 19:45:36 +0000149 ParseScope LinkageScope(this, Scope::DeclScope);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000150 DeclPtrTy LinkageSpec
Douglas Gregord8028382009-01-05 19:45:36 +0000151 = Actions.ActOnStartLinkageSpecification(CurScope,
152 /*FIXME: */SourceLocation(),
153 Loc, LangBufPtr, StrSize,
154 Tok.is(tok::l_brace)? Tok.getLocation()
155 : SourceLocation());
156
157 if (Tok.isNot(tok::l_brace)) {
158 ParseDeclarationOrFunctionDefinition();
159 return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec,
160 SourceLocation());
Douglas Gregorad17e372008-12-16 22:23:02 +0000161 }
162
163 SourceLocation LBrace = ConsumeBrace();
Douglas Gregorad17e372008-12-16 22:23:02 +0000164 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
Douglas Gregord8028382009-01-05 19:45:36 +0000165 ParseExternalDeclaration();
Chris Lattner806a5f52008-01-12 07:05:38 +0000166 }
167
Douglas Gregorad17e372008-12-16 22:23:02 +0000168 SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
Douglas Gregord8028382009-01-05 19:45:36 +0000169 return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, RBrace);
Chris Lattner806a5f52008-01-12 07:05:38 +0000170}
Douglas Gregorec93f442008-04-13 21:30:24 +0000171
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000172/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
173/// using-directive. Assumes that current token is 'using'.
Chris Lattner5261d0c2009-03-28 19:18:32 +0000174Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context) {
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000175 assert(Tok.is(tok::kw_using) && "Not using token");
176
177 // Eat 'using'.
178 SourceLocation UsingLoc = ConsumeToken();
179
Chris Lattner08ab4162009-01-06 06:55:51 +0000180 if (Tok.is(tok::kw_namespace))
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000181 // Next token after 'using' is 'namespace' so it must be using-directive
182 return ParseUsingDirective(Context, UsingLoc);
Chris Lattner08ab4162009-01-06 06:55:51 +0000183
184 // Otherwise, it must be using-declaration.
185 return ParseUsingDeclaration(Context, UsingLoc);
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000186}
187
188/// ParseUsingDirective - Parse C++ using-directive, assumes
189/// that current token is 'namespace' and 'using' was already parsed.
190///
191/// using-directive: [C++ 7.3.p4: namespace.udir]
192/// 'using' 'namespace' ::[opt] nested-name-specifier[opt]
193/// namespace-name ;
194/// [GNU] using-directive:
195/// 'using' 'namespace' ::[opt] nested-name-specifier[opt]
196/// namespace-name attributes[opt] ;
197///
Chris Lattner5261d0c2009-03-28 19:18:32 +0000198Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
199 SourceLocation UsingLoc) {
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000200 assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
201
202 // Eat 'namespace'.
203 SourceLocation NamespcLoc = ConsumeToken();
204
205 CXXScopeSpec SS;
206 // Parse (optional) nested-name-specifier.
Chris Lattnerd706dc82009-01-06 06:59:53 +0000207 ParseOptionalCXXScopeSpecifier(SS);
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000208
209 AttributeList *AttrList = 0;
210 IdentifierInfo *NamespcName = 0;
211 SourceLocation IdentLoc = SourceLocation();
212
213 // Parse namespace-name.
Chris Lattner7898bf62009-01-06 07:27:21 +0000214 if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000215 Diag(Tok, diag::err_expected_namespace_name);
216 // If there was invalid namespace name, skip to end of decl, and eat ';'.
217 SkipUntil(tok::semi);
218 // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
Chris Lattner5261d0c2009-03-28 19:18:32 +0000219 return DeclPtrTy();
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000220 }
Chris Lattner7898bf62009-01-06 07:27:21 +0000221
222 // Parse identifier.
223 NamespcName = Tok.getIdentifierInfo();
224 IdentLoc = ConsumeToken();
225
226 // Parse (optional) attributes (most likely GNU strong-using extension).
227 if (Tok.is(tok::kw___attribute))
228 AttrList = ParseAttributes();
229
230 // Eat ';'.
231 ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
232 AttrList ? "attributes list" : "namespace name", tok::semi);
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000233
234 return Actions.ActOnUsingDirective(CurScope, UsingLoc, NamespcLoc, SS,
Chris Lattner7898bf62009-01-06 07:27:21 +0000235 IdentLoc, NamespcName, AttrList);
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000236}
237
238/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that
239/// 'using' was already seen.
240///
241/// using-declaration: [C++ 7.3.p3: namespace.udecl]
242/// 'using' 'typename'[opt] ::[opt] nested-name-specifier
243/// unqualified-id [TODO]
244/// 'using' :: unqualified-id [TODO]
245///
Chris Lattner5261d0c2009-03-28 19:18:32 +0000246Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
247 SourceLocation UsingLoc) {
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000248 assert(false && "Not implemented");
249 // FIXME: Implement parsing.
Chris Lattner5261d0c2009-03-28 19:18:32 +0000250 return DeclPtrTy();
Douglas Gregor5ff0ee52008-12-30 03:27:21 +0000251}
252
Anders Carlssonab041982009-03-11 16:27:10 +0000253/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
254///
255/// static_assert-declaration:
256/// static_assert ( constant-expression , string-literal ) ;
257///
Chris Lattner5261d0c2009-03-28 19:18:32 +0000258Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration() {
Anders Carlssonab041982009-03-11 16:27:10 +0000259 assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
260 SourceLocation StaticAssertLoc = ConsumeToken();
261
262 if (Tok.isNot(tok::l_paren)) {
263 Diag(Tok, diag::err_expected_lparen);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000264 return DeclPtrTy();
Anders Carlssonab041982009-03-11 16:27:10 +0000265 }
266
267 SourceLocation LParenLoc = ConsumeParen();
268
269 OwningExprResult AssertExpr(ParseConstantExpression());
270 if (AssertExpr.isInvalid()) {
271 SkipUntil(tok::semi);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000272 return DeclPtrTy();
Anders Carlssonab041982009-03-11 16:27:10 +0000273 }
274
Anders Carlssona24e8d52009-03-13 23:29:20 +0000275 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
Chris Lattner5261d0c2009-03-28 19:18:32 +0000276 return DeclPtrTy();
Anders Carlssona24e8d52009-03-13 23:29:20 +0000277
Anders Carlssonab041982009-03-11 16:27:10 +0000278 if (Tok.isNot(tok::string_literal)) {
279 Diag(Tok, diag::err_expected_string_literal);
280 SkipUntil(tok::semi);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000281 return DeclPtrTy();
Anders Carlssonab041982009-03-11 16:27:10 +0000282 }
283
284 OwningExprResult AssertMessage(ParseStringLiteralExpression());
285 if (AssertMessage.isInvalid())
Chris Lattner5261d0c2009-03-28 19:18:32 +0000286 return DeclPtrTy();
Anders Carlssonab041982009-03-11 16:27:10 +0000287
Anders Carlssonc45057a2009-03-15 18:44:04 +0000288 MatchRHSPunctuation(tok::r_paren, LParenLoc);
Anders Carlssonab041982009-03-11 16:27:10 +0000289
290 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert);
291
Anders Carlssona24e8d52009-03-13 23:29:20 +0000292 return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, move(AssertExpr),
Anders Carlssonc45057a2009-03-15 18:44:04 +0000293 move(AssertMessage));
Anders Carlssonab041982009-03-11 16:27:10 +0000294}
295
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000296/// ParseClassName - Parse a C++ class-name, which names a class. Note
297/// that we only check that the result names a type; semantic analysis
298/// will need to verify that the type names a class. The result is
Douglas Gregor7bbed2a2009-02-25 23:52:28 +0000299/// either a type or NULL, depending on whether a type name was
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000300/// found.
301///
302/// class-name: [C++ 9.1]
303/// identifier
Douglas Gregor7bbed2a2009-02-25 23:52:28 +0000304/// simple-template-id
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000305///
Douglas Gregor7bbed2a2009-02-25 23:52:28 +0000306Parser::TypeTy *Parser::ParseClassName(SourceLocation &EndLocation,
307 const CXXScopeSpec *SS) {
308 // Check whether we have a template-id that names a type.
309 if (Tok.is(tok::annot_template_id)) {
310 TemplateIdAnnotation *TemplateId
311 = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
312 if (TemplateId->Kind == TNK_Class_template) {
313 if (AnnotateTemplateIdTokenAsType(SS))
314 return 0;
315
316 assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
317 TypeTy *Type = Tok.getAnnotationValue();
318 EndLocation = Tok.getAnnotationEndLoc();
319 ConsumeToken();
320 return Type;
321 }
322
323 // Fall through to produce an error below.
324 }
325
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000326 if (Tok.isNot(tok::identifier)) {
Chris Lattnerf006a222008-11-18 07:48:38 +0000327 Diag(Tok, diag::err_expected_class_name);
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000328 return 0;
329 }
330
331 // We have an identifier; check whether it is actually a type.
Douglas Gregor1075a162009-02-04 17:00:24 +0000332 TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(),
333 Tok.getLocation(), CurScope, SS);
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000334 if (!Type) {
Chris Lattnerf006a222008-11-18 07:48:38 +0000335 Diag(Tok, diag::err_expected_class_name);
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000336 return 0;
337 }
338
339 // Consume the identifier.
Douglas Gregor7bbed2a2009-02-25 23:52:28 +0000340 EndLocation = ConsumeToken();
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000341 return Type;
342}
343
Douglas Gregorec93f442008-04-13 21:30:24 +0000344/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
345/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
346/// until we reach the start of a definition or see a token that
347/// cannot start a definition.
348///
349/// class-specifier: [C++ class]
350/// class-head '{' member-specification[opt] '}'
351/// class-head '{' member-specification[opt] '}' attributes[opt]
352/// class-head:
353/// class-key identifier[opt] base-clause[opt]
354/// class-key nested-name-specifier identifier base-clause[opt]
355/// class-key nested-name-specifier[opt] simple-template-id
356/// base-clause[opt]
357/// [GNU] class-key attributes[opt] identifier[opt] base-clause[opt]
358/// [GNU] class-key attributes[opt] nested-name-specifier
359/// identifier base-clause[opt]
360/// [GNU] class-key attributes[opt] nested-name-specifier[opt]
361/// simple-template-id base-clause[opt]
362/// class-key:
363/// 'class'
364/// 'struct'
365/// 'union'
366///
367/// elaborated-type-specifier: [C++ dcl.type.elab]
368/// class-key ::[opt] nested-name-specifier[opt] identifier
369/// class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
370/// simple-template-id
371///
372/// Note that the C++ class-specifier and elaborated-type-specifier,
373/// together, subsume the C99 struct-or-union-specifier:
374///
375/// struct-or-union-specifier: [C99 6.7.2.1]
376/// struct-or-union identifier[opt] '{' struct-contents '}'
377/// struct-or-union identifier
378/// [GNU] struct-or-union attributes[opt] identifier[opt] '{' struct-contents
379/// '}' attributes[opt]
380/// [GNU] struct-or-union attributes[opt] identifier
381/// struct-or-union:
382/// 'struct'
383/// 'union'
Douglas Gregor52473432008-12-24 02:52:09 +0000384void Parser::ParseClassSpecifier(DeclSpec &DS,
Douglas Gregor0c793bb2009-03-25 22:00:53 +0000385 TemplateParameterLists *TemplateParams,
386 AccessSpecifier AS) {
Douglas Gregorec93f442008-04-13 21:30:24 +0000387 assert((Tok.is(tok::kw_class) ||
388 Tok.is(tok::kw_struct) ||
389 Tok.is(tok::kw_union)) &&
390 "Not a class specifier");
391 DeclSpec::TST TagType =
392 Tok.is(tok::kw_class) ? DeclSpec::TST_class :
393 Tok.is(tok::kw_struct) ? DeclSpec::TST_struct :
394 DeclSpec::TST_union;
395
396 SourceLocation StartLoc = ConsumeToken();
397
398 AttributeList *Attr = 0;
399 // If attributes exist after tag, parse them.
400 if (Tok.is(tok::kw___attribute))
401 Attr = ParseAttributes();
402
Steve Naroffc5ab14f2008-12-24 20:59:21 +0000403 // If declspecs exist after tag, parse them.
404 if (Tok.is(tok::kw___declspec) && PP.getLangOptions().Microsoft)
405 FuzzyParseMicrosoftDeclSpec();
406
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000407 // Parse the (optional) nested-name-specifier.
408 CXXScopeSpec SS;
Douglas Gregor0c281a82009-02-25 19:37:18 +0000409 if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS))
410 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000411 Diag(Tok, diag::err_expected_ident);
Douglas Gregora08b6c72009-02-17 23:15:12 +0000412
413 // Parse the (optional) class name or simple-template-id.
Douglas Gregorec93f442008-04-13 21:30:24 +0000414 IdentifierInfo *Name = 0;
415 SourceLocation NameLoc;
Douglas Gregor0c281a82009-02-25 19:37:18 +0000416 TemplateIdAnnotation *TemplateId = 0;
Douglas Gregorec93f442008-04-13 21:30:24 +0000417 if (Tok.is(tok::identifier)) {
418 Name = Tok.getIdentifierInfo();
419 NameLoc = ConsumeToken();
Douglas Gregor0c281a82009-02-25 19:37:18 +0000420 } else if (Tok.is(tok::annot_template_id)) {
421 TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
422 NameLoc = ConsumeToken();
Douglas Gregora08b6c72009-02-17 23:15:12 +0000423
Douglas Gregor0c281a82009-02-25 19:37:18 +0000424 if (TemplateId->Kind != TNK_Class_template) {
425 // The template-name in the simple-template-id refers to
426 // something other than a class template. Give an appropriate
427 // error message and skip to the ';'.
428 SourceRange Range(NameLoc);
429 if (SS.isNotEmpty())
430 Range.setBegin(SS.getBeginLoc());
Douglas Gregora08b6c72009-02-17 23:15:12 +0000431
Douglas Gregor0c281a82009-02-25 19:37:18 +0000432 Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
433 << Name << static_cast<int>(TemplateId->Kind) << Range;
Douglas Gregora08b6c72009-02-17 23:15:12 +0000434
Douglas Gregor0c281a82009-02-25 19:37:18 +0000435 DS.SetTypeSpecError();
436 SkipUntil(tok::semi, false, true);
437 TemplateId->Destroy();
438 return;
Douglas Gregora08b6c72009-02-17 23:15:12 +0000439 }
Douglas Gregorec93f442008-04-13 21:30:24 +0000440 }
441
442 // There are three options here. If we have 'struct foo;', then
443 // this is a forward declaration. If we have 'struct foo {...' or
Douglas Gregor0c281a82009-02-25 19:37:18 +0000444 // 'struct foo :...' then this is a definition. Otherwise we have
Douglas Gregorec93f442008-04-13 21:30:24 +0000445 // something like 'struct foo xyz', a reference.
446 Action::TagKind TK;
447 if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon)))
448 TK = Action::TK_Definition;
449 else if (Tok.is(tok::semi))
450 TK = Action::TK_Declaration;
451 else
452 TK = Action::TK_Reference;
453
Douglas Gregor0c281a82009-02-25 19:37:18 +0000454 if (!Name && !TemplateId && TK != Action::TK_Definition) {
Douglas Gregorec93f442008-04-13 21:30:24 +0000455 // We have a declaration or reference to an anonymous class.
Chris Lattnerf006a222008-11-18 07:48:38 +0000456 Diag(StartLoc, diag::err_anon_type_definition)
457 << DeclSpec::getSpecifierName(TagType);
Douglas Gregorec93f442008-04-13 21:30:24 +0000458
459 // Skip the rest of this declarator, up until the comma or semicolon.
460 SkipUntil(tok::comma, true);
Douglas Gregor0c281a82009-02-25 19:37:18 +0000461
462 if (TemplateId)
463 TemplateId->Destroy();
Douglas Gregorec93f442008-04-13 21:30:24 +0000464 return;
465 }
466
Douglas Gregord406b032009-02-06 22:42:48 +0000467 // Create the tag portion of the class or class template.
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000468 Action::DeclResult TagOrTempResult;
Douglas Gregor0c281a82009-02-25 19:37:18 +0000469 if (TemplateId && TK != Action::TK_Reference) {
Douglas Gregora08b6c72009-02-17 23:15:12 +0000470 // Explicit specialization or class template partial
471 // specialization. Let semantic analysis decide.
Douglas Gregor0c281a82009-02-25 19:37:18 +0000472 ASTTemplateArgsPtr TemplateArgsPtr(Actions,
473 TemplateId->getTemplateArgs(),
474 TemplateId->getTemplateArgIsType(),
475 TemplateId->NumArgs);
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000476 TagOrTempResult
Douglas Gregora08b6c72009-02-17 23:15:12 +0000477 = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TK,
Douglas Gregor0c281a82009-02-25 19:37:18 +0000478 StartLoc, SS,
Chris Lattner5261d0c2009-03-28 19:18:32 +0000479 DeclPtrTy::make(TemplateId->Template),
Douglas Gregor0c281a82009-02-25 19:37:18 +0000480 TemplateId->TemplateNameLoc,
481 TemplateId->LAngleLoc,
482 TemplateArgsPtr,
483 TemplateId->getTemplateArgLocations(),
484 TemplateId->RAngleLoc,
485 Attr,
Douglas Gregora08b6c72009-02-17 23:15:12 +0000486 Action::MultiTemplateParamsArg(Actions,
487 TemplateParams? &(*TemplateParams)[0] : 0,
488 TemplateParams? TemplateParams->size() : 0));
Douglas Gregor0c281a82009-02-25 19:37:18 +0000489 TemplateId->Destroy();
490 } else if (TemplateParams && TK != Action::TK_Reference)
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000491 TagOrTempResult = Actions.ActOnClassTemplate(CurScope, TagType, TK,
492 StartLoc, SS, Name, NameLoc,
493 Attr,
Douglas Gregord406b032009-02-06 22:42:48 +0000494 Action::MultiTemplateParamsArg(Actions,
495 &(*TemplateParams)[0],
Anders Carlssoned20fb92009-03-26 00:52:18 +0000496 TemplateParams->size()),
497 AS);
Douglas Gregord406b032009-02-06 22:42:48 +0000498 else
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000499 TagOrTempResult = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS, Name,
Douglas Gregor0c793bb2009-03-25 22:00:53 +0000500 NameLoc, Attr, AS);
Douglas Gregorec93f442008-04-13 21:30:24 +0000501
502 // Parse the optional base clause (C++ only).
Chris Lattner31ccf0a2009-02-16 22:07:16 +0000503 if (getLang().CPlusPlus && Tok.is(tok::colon))
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000504 ParseBaseClause(TagOrTempResult.get());
Douglas Gregorec93f442008-04-13 21:30:24 +0000505
506 // If there is a body, parse it and inform the actions module.
507 if (Tok.is(tok::l_brace))
Argiris Kirtzidis38f16712008-07-01 10:37:29 +0000508 if (getLang().CPlusPlus)
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000509 ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
Argiris Kirtzidis38f16712008-07-01 10:37:29 +0000510 else
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000511 ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
Douglas Gregorec93f442008-04-13 21:30:24 +0000512 else if (TK == Action::TK_Definition) {
513 // FIXME: Complain that we have a base-specifier list but no
514 // definition.
Chris Lattnerf006a222008-11-18 07:48:38 +0000515 Diag(Tok, diag::err_expected_lbrace);
Douglas Gregorec93f442008-04-13 21:30:24 +0000516 }
517
518 const char *PrevSpec = 0;
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000519 if (TagOrTempResult.isInvalid())
Douglas Gregord406b032009-02-06 22:42:48 +0000520 DS.SetTypeSpecError();
Douglas Gregorc5d6fa72009-03-25 00:13:59 +0000521 else if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec,
Chris Lattner5261d0c2009-03-28 19:18:32 +0000522 TagOrTempResult.get().getAs<void>()))
Chris Lattnerf006a222008-11-18 07:48:38 +0000523 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
Douglas Gregorec93f442008-04-13 21:30:24 +0000524}
525
526/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
527///
528/// base-clause : [C++ class.derived]
529/// ':' base-specifier-list
530/// base-specifier-list:
531/// base-specifier '...'[opt]
532/// base-specifier-list ',' base-specifier '...'[opt]
Chris Lattner5261d0c2009-03-28 19:18:32 +0000533void Parser::ParseBaseClause(DeclPtrTy ClassDecl) {
Douglas Gregorec93f442008-04-13 21:30:24 +0000534 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
Chris Lattner5261d0c2009-03-28 19:18:32 +0000575Parser::BaseResult Parser::ParseBaseSpecifier(DeclPtrTy ClassDecl) {
Douglas Gregorec93f442008-04-13 21:30:24 +0000576 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 Lattnerf006a222008-11-18 07:48:38 +0000596 Diag(VirtualLoc, diag::err_dup_virtual)
597 << SourceRange(VirtualLoc, VirtualLoc);
Douglas Gregorec93f442008-04-13 21:30:24 +0000598 }
599
600 IsVirtual = true;
601 }
602
Argiris Kirtzidis311db8c2008-11-08 16:45:02 +0000603 // Parse optional '::' and optional nested-name-specifier.
604 CXXScopeSpec SS;
Chris Lattnerd706dc82009-01-06 06:59:53 +0000605 ParseOptionalCXXScopeSpecifier(SS);
Douglas Gregorec93f442008-04-13 21:30:24 +0000606
Douglas Gregorec93f442008-04-13 21:30:24 +0000607 // The location of the base class itself.
608 SourceLocation BaseLoc = Tok.getLocation();
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000609
610 // Parse the class-name.
Douglas Gregor7bbed2a2009-02-25 23:52:28 +0000611 SourceLocation EndLocation;
612 TypeTy *BaseType = ParseClassName(EndLocation, &SS);
Douglas Gregor8210a8e2008-11-05 20:51:48 +0000613 if (!BaseType)
614 return true;
Douglas Gregorec93f442008-04-13 21:30:24 +0000615
616 // Find the complete source range for the base-specifier.
Douglas Gregor7bbed2a2009-02-25 23:52:28 +0000617 SourceRange Range(StartLoc, EndLocation);
Douglas Gregorec93f442008-04-13 21:30:24 +0000618
Douglas Gregorec93f442008-04-13 21:30:24 +0000619 // Notify semantic analysis that we have parsed a complete
620 // base-specifier.
Sebastian Redl6008ac32008-11-25 22:21:31 +0000621 return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
622 BaseType, BaseLoc);
Douglas Gregorec93f442008-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 Gregor696be932008-04-14 00:13:42 +0000632AccessSpecifier Parser::getAccessSpecifierIfPresent() const
Douglas Gregorec93f442008-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}
Argiris Kirtzidis9d784332008-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 Carlssonab041982009-03-11 16:27:10 +0000649/// [C++0x] static_assert-declaration
Anders Carlssoned20fb92009-03-26 00:52:18 +0000650/// template-declaration
Chris Lattnerf3375de2008-12-18 01:12:00 +0000651/// [GNU] '__extension__' member-declaration
Argiris Kirtzidis9d784332008-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///
Chris Lattner5261d0c2009-03-28 19:18:32 +0000668Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
Anders Carlssonab041982009-03-11 16:27:10 +0000669 // static_assert-declaration
670 if (Tok.is(tok::kw_static_assert))
671 return ParseStaticAssertDeclaration();
672
Anders Carlssoned20fb92009-03-26 00:52:18 +0000673 if (Tok.is(tok::kw_template))
674 return ParseTemplateDeclarationOrSpecialization(Declarator::MemberContext,
675 AS);
676
Chris Lattnerf3375de2008-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
Argiris Kirtzidis9d784332008-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 Gregor0c793bb2009-03-25 22:00:53 +0000689 ParseDeclarationSpecifiers(DS, 0, AS);
Argiris Kirtzidis9d784332008-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);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000704 return DeclPtrTy();
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000705 }
706 }
Argiris Kirtzidis38f16712008-07-01 10:37:29 +0000707
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000708 Declarator DeclaratorInfo(DS, Declarator::MemberContext);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000709
Argiris Kirtzidisf8009b42008-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 Gregor6704b312008-11-17 22:58:34 +0000714 if (!DeclaratorInfo.hasName()) {
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000715 // If so, skip until the semi-colon or a }.
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000716 SkipUntil(tok::r_brace, true);
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000717 if (Tok.is(tok::semi))
718 ConsumeToken();
Chris Lattner5261d0c2009-03-28 19:18:32 +0000719 return DeclPtrTy();
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000720 }
721
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000722 // function-definition:
Douglas Gregora65e8dd2008-11-05 04:29:56 +0000723 if (Tok.is(tok::l_brace)
724 || (DeclaratorInfo.isFunctionDeclarator() && Tok.is(tok::colon))) {
Argiris Kirtzidisf8009b42008-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);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000729 return DeclPtrTy();
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000730 }
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000731
Argiris Kirtzidisf8009b42008-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);
Chris Lattner5261d0c2009-03-28 19:18:32 +0000739 return DeclPtrTy();
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000740 }
741
742 return ParseCXXInlineMethodDef(AS, DeclaratorInfo);
743 }
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000744 }
745
746 // member-declarator-list:
747 // member-declarator
748 // member-declarator-list ',' member-declarator
749
Chris Lattner5261d0c2009-03-28 19:18:32 +0000750 DeclPtrTy LastDeclInGroup;
Sebastian Redl62261042008-12-09 20:22:58 +0000751 OwningExprResult BitfieldSize(Actions);
752 OwningExprResult Init(Actions);
Argiris Kirtzidis9d784332008-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 Redlbb4dae72008-12-09 13:15:23 +0000763 BitfieldSize = ParseConstantExpression();
764 if (BitfieldSize.isInvalid())
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000765 SkipUntil(tok::comma, true, true);
Argiris Kirtzidis9d784332008-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 Redlbb4dae72008-12-09 13:15:23 +0000776 Init = ParseInitializer();
777 if (Init.isInvalid())
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000778 SkipUntil(tok::comma, true, true);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000779 }
780
781 // If attributes exist after the declarator, parse them.
Sebastian Redl0c986032009-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 }
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000787
Argiris Kirtzidis38f16712008-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.
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000792 LastDeclInGroup = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
793 DeclaratorInfo,
Sebastian Redl6f1ee232008-12-10 00:02:53 +0000794 BitfieldSize.release(),
795 Init.release(),
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000796 LastDeclInGroup);
797
Douglas Gregor605de8d2008-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
Argiris Kirtzidis9d784332008-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 Redl62261042008-12-09 20:22:58 +0000842 BitfieldSize = 0;
843 Init = 0;
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000844
845 // Attributes are only allowed on the second declarator.
Sebastian Redl0c986032009-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 }
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000851
Argiris Kirtzidisf8009b42008-06-28 08:10:48 +0000852 if (Tok.isNot(tok::colon))
853 ParseDeclarator(DeclaratorInfo);
Argiris Kirtzidis9d784332008-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();
Chris Lattner5261d0c2009-03-28 19:18:32 +0000867 return DeclPtrTy();
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000868}
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,
Chris Lattner5261d0c2009-03-28 19:18:32 +0000877 unsigned TagType, DeclPtrTy TagDecl) {
Sanjiv Guptafa451432008-10-31 09:52:39 +0000878 assert((TagType == DeclSpec::TST_struct ||
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000879 TagType == DeclSpec::TST_union ||
Sanjiv Guptafa451432008-10-31 09:52:39 +0000880 TagType == DeclSpec::TST_class) && "Invalid TagType!");
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000881
Chris Lattnerc309ade2009-03-05 08:00:35 +0000882 PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
883 PP.getSourceManager(),
884 "parsing struct/union/class body");
Chris Lattner7efd75e2009-03-05 02:25:03 +0000885
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000886 SourceLocation LBraceLoc = ConsumeBrace();
887
Douglas Gregorcab994d2009-01-09 22:42:13 +0000888 if (!CurScope->isClassScope() && // Not about to define a nested class.
Argiris Kirtzidis9d784332008-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 Gregorcab994d2009-01-09 22:42:13 +0000896 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000897
Douglas Gregord406b032009-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 }
Argiris Kirtzidis9d784332008-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 Gregor605de8d2008-12-16 21:30:33 +0000953 // FIXME: Only function bodies and constructor ctor-initializers are
954 // parsed correctly, fix the rest.
Douglas Gregorcab994d2009-01-09 22:42:13 +0000955 if (!CurScope->getParent()->isClassScope()) {
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000956 // We are not inside a nested class. This class and its nested classes
Douglas Gregor605de8d2008-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();
Argiris Kirtzidis9d784332008-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 Guptafa451432008-10-31 09:52:39 +0000965 assert((CurScope->isInCXXInlineMethodScope() ||
966 TopClassStacks.size() == 1) &&
Argiris Kirtzidis9d784332008-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 Gregor95d40792008-12-10 06:34:36 +0000973 ClassScope.Exit();
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000974
Douglas Gregordb568cf2009-01-08 20:45:30 +0000975 Actions.ActOnTagFinishDefinition(CurScope, TagDecl);
Argiris Kirtzidis9d784332008-06-24 22:12:16 +0000976}
Douglas Gregora65e8dd2008-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
Chris Lattner5261d0c2009-03-28 19:18:32 +0000999void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) {
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001000 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 Gregor10a18fc2009-01-26 22:44:13 +00001008 if (!MemInit.isInvalid())
1009 MemInitializers.push_back(MemInit.get());
Douglas Gregora65e8dd2008-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
Chris Lattner5261d0c2009-03-28 19:18:32 +00001037Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001038 // FIXME: parse '::'[opt] nested-name-specifier[opt]
1039
1040 if (Tok.isNot(tok::identifier)) {
Chris Lattnerf006a222008-11-18 07:48:38 +00001041 Diag(Tok, diag::err_expected_member_or_base_name);
Douglas Gregora65e8dd2008-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 Lattnerf006a222008-11-18 07:48:38 +00001052 Diag(Tok, diag::err_expected_lparen);
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001053 return true;
1054 }
1055 SourceLocation LParenLoc = ConsumeParen();
1056
1057 // Parse the optional expression-list.
Sebastian Redl6008ac32008-11-25 22:21:31 +00001058 ExprVector ArgExprs(Actions);
Douglas Gregora65e8dd2008-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 Redl6008ac32008-11-25 22:21:31 +00001067 return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, II, IdLoc,
1068 LParenLoc, ArgExprs.take(),
1069 ArgExprs.size(), &CommaLocs[0], RParenLoc);
Douglas Gregora65e8dd2008-11-05 04:29:56 +00001070}
Douglas Gregor90a2c972008-11-25 03:22:00 +00001071
1072/// ParseExceptionSpecification - Parse a C++ exception-specification
1073/// (C++ [except.spec]).
1074///
Douglas Gregor9ed9ac82008-12-01 18:00:20 +00001075/// exception-specification:
1076/// 'throw' '(' type-id-list [opt] ')'
1077/// [MS] 'throw' '(' '...' ')'
Douglas Gregor90a2c972008-11-25 03:22:00 +00001078///
Douglas Gregor9ed9ac82008-12-01 18:00:20 +00001079/// type-id-list:
1080/// type-id
1081/// type-id-list ',' type-id
Douglas Gregor90a2c972008-11-25 03:22:00 +00001082///
Sebastian Redl0c986032009-02-09 18:23:29 +00001083bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc) {
Douglas Gregor90a2c972008-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 Gregor9ed9ac82008-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 Redl0c986032009-02-09 18:23:29 +00001099 EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Douglas Gregor9ed9ac82008-12-01 18:00:20 +00001100 return false;
1101 }
1102
Douglas Gregor90a2c972008-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 Redl0c986032009-02-09 18:23:29 +00001112 EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Douglas Gregor90a2c972008-11-25 03:22:00 +00001113 return false;
1114}