blob: c50a033e561347b105037eee0f1b3a22a97d6dec [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///
Chris Lattnerb28317a2009-03-28 19:18:32 +000045Parser::DeclPtrTy 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.
Chris Lattnerb28317a2009-03-28 19:18:32 +000058 Action::AttrTy *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 Carlsson03bd5a12009-03-28 22:53:22 +000065 return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident);
Anders Carlssonf67606a2009-03-28 04:07:16 +000066
Chris Lattner51448322009-03-29 14:02:43 +000067 if (Tok.isNot(tok::l_brace)) {
Chris Lattner1ab3b962008-11-18 07:48:38 +000068 Diag(Tok, Ident ? diag::err_expected_lbrace :
Chris Lattner51448322009-03-29 14:02:43 +000069 diag::err_expected_ident_lbrace);
70 return DeclPtrTy();
Chris Lattner8f08cb72007-08-25 06:57:03 +000071 }
72
Chris Lattner51448322009-03-29 14:02:43 +000073 SourceLocation LBrace = ConsumeBrace();
74
75 // Enter a scope for the namespace.
76 ParseScope NamespaceScope(this, Scope::DeclScope);
77
78 DeclPtrTy NamespcDecl =
79 Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace);
80
81 PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions,
82 PP.getSourceManager(),
83 "parsing namespace");
84
85 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof))
86 ParseExternalDeclaration();
87
88 // Leave the namespace scope.
89 NamespaceScope.Exit();
90
91 SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
92 Actions.ActOnFinishNamespaceDef(NamespcDecl, RBrace);
93
94 return NamespcDecl;
Chris Lattner8f08cb72007-08-25 06:57:03 +000095}
Chris Lattnerc6fdc342008-01-12 07:05:38 +000096
Anders Carlssonf67606a2009-03-28 04:07:16 +000097/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
98/// alias definition.
99///
Anders Carlsson03bd5a12009-03-28 22:53:22 +0000100Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
101 SourceLocation AliasLoc,
Chris Lattnerb28317a2009-03-28 19:18:32 +0000102 IdentifierInfo *Alias) {
Anders Carlssonf67606a2009-03-28 04:07:16 +0000103 assert(Tok.is(tok::equal) && "Not equal token");
104
105 ConsumeToken(); // eat the '='.
106
107 CXXScopeSpec SS;
108 // Parse (optional) nested-name-specifier.
109 ParseOptionalCXXScopeSpecifier(SS);
110
111 if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
112 Diag(Tok, diag::err_expected_namespace_name);
113 // Skip to end of the definition and eat the ';'.
114 SkipUntil(tok::semi);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000115 return DeclPtrTy();
Anders Carlssonf67606a2009-03-28 04:07:16 +0000116 }
117
118 // Parse identifier.
Anders Carlsson03bd5a12009-03-28 22:53:22 +0000119 IdentifierInfo *Ident = Tok.getIdentifierInfo();
120 SourceLocation IdentLoc = ConsumeToken();
Anders Carlssonf67606a2009-03-28 04:07:16 +0000121
122 // Eat the ';'.
123 ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
124 "namespace name", tok::semi);
125
Anders Carlsson03bd5a12009-03-28 22:53:22 +0000126 return Actions.ActOnNamespaceAliasDef(CurScope, NamespaceLoc, AliasLoc, Alias,
127 SS, IdentLoc, Ident);
Anders Carlssonf67606a2009-03-28 04:07:16 +0000128}
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///
Chris Lattnerb28317a2009-03-28 19:18:32 +0000137Parser::DeclPtrTy 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);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000148 DeclPtrTy LinkageSpec
Douglas Gregor074149e2009-01-05 19:45:36 +0000149 = 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 Lattnerb28317a2009-03-28 19:18:32 +0000172Parser::DeclPtrTy 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///
Chris Lattnerb28317a2009-03-28 19:18:32 +0000196Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
197 SourceLocation UsingLoc) {
Douglas Gregorf780abc2008-12-30 03:27:21 +0000198 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?
Chris Lattnerb28317a2009-03-28 19:18:32 +0000217 return DeclPtrTy();
Douglas Gregorf780abc2008-12-30 03:27:21 +0000218 }
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///
Chris Lattnerb28317a2009-03-28 19:18:32 +0000244Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
245 SourceLocation UsingLoc) {
Douglas Gregorf780abc2008-12-30 03:27:21 +0000246 assert(false && "Not implemented");
247 // FIXME: Implement parsing.
Chris Lattnerb28317a2009-03-28 19:18:32 +0000248 return DeclPtrTy();
Douglas Gregorf780abc2008-12-30 03:27:21 +0000249}
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///
Chris Lattnerb28317a2009-03-28 19:18:32 +0000256Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration() {
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000257 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);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000262 return DeclPtrTy();
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000263 }
264
265 SourceLocation LParenLoc = ConsumeParen();
266
267 OwningExprResult AssertExpr(ParseConstantExpression());
268 if (AssertExpr.isInvalid()) {
269 SkipUntil(tok::semi);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000270 return DeclPtrTy();
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000271 }
272
Anders Carlssonad5f9602009-03-13 23:29:20 +0000273 if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
Chris Lattnerb28317a2009-03-28 19:18:32 +0000274 return DeclPtrTy();
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);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000279 return DeclPtrTy();
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000280 }
281
282 OwningExprResult AssertMessage(ParseStringLiteralExpression());
283 if (AssertMessage.isInvalid())
Chris Lattnerb28317a2009-03-28 19:18:32 +0000284 return DeclPtrTy();
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000285
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,
Chris Lattnerb28317a2009-03-28 19:18:32 +0000477 DeclPtrTy::make(TemplateId->Template),
Douglas Gregor39a8de12009-02-25 19:37:18 +0000478 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,
Chris Lattnerb28317a2009-03-28 19:18:32 +0000520 TagOrTempResult.get().getAs<void>()))
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]
Chris Lattnerb28317a2009-03-28 19:18:32 +0000531void Parser::ParseBaseClause(DeclPtrTy ClassDecl) {
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000532 assert(Tok.is(tok::colon) && "Not a base clause");
533 ConsumeToken();
534
Douglas Gregorf8268ae2008-10-22 17:49:05 +0000535 // Build up an array of parsed base specifiers.
536 llvm::SmallVector<BaseTy *, 8> BaseInfo;
537
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000538 while (true) {
539 // Parse a base-specifier.
Douglas Gregorf8268ae2008-10-22 17:49:05 +0000540 BaseResult Result = ParseBaseSpecifier(ClassDecl);
Douglas Gregor5ac8aff2009-01-26 22:44:13 +0000541 if (Result.isInvalid()) {
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000542 // Skip the rest of this base specifier, up until the comma or
543 // opening brace.
Douglas Gregorf8268ae2008-10-22 17:49:05 +0000544 SkipUntil(tok::comma, tok::l_brace, true, true);
545 } else {
546 // Add this to our array of base specifiers.
Douglas Gregor5ac8aff2009-01-26 22:44:13 +0000547 BaseInfo.push_back(Result.get());
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000548 }
549
550 // If the next token is a comma, consume it and keep reading
551 // base-specifiers.
552 if (Tok.isNot(tok::comma)) break;
553
554 // Consume the comma.
555 ConsumeToken();
556 }
Douglas Gregorf8268ae2008-10-22 17:49:05 +0000557
558 // Attach the base specifiers
559 Actions.ActOnBaseSpecifiers(ClassDecl, &BaseInfo[0], BaseInfo.size());
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000560}
561
562/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
563/// one entry in the base class list of a class specifier, for example:
564/// class foo : public bar, virtual private baz {
565/// 'public bar' and 'virtual private baz' are each base-specifiers.
566///
567/// base-specifier: [C++ class.derived]
568/// ::[opt] nested-name-specifier[opt] class-name
569/// 'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt]
570/// class-name
571/// access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
572/// class-name
Chris Lattnerb28317a2009-03-28 19:18:32 +0000573Parser::BaseResult Parser::ParseBaseSpecifier(DeclPtrTy ClassDecl) {
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000574 bool IsVirtual = false;
575 SourceLocation StartLoc = Tok.getLocation();
576
577 // Parse the 'virtual' keyword.
578 if (Tok.is(tok::kw_virtual)) {
579 ConsumeToken();
580 IsVirtual = true;
581 }
582
583 // Parse an (optional) access specifier.
584 AccessSpecifier Access = getAccessSpecifierIfPresent();
585 if (Access)
586 ConsumeToken();
587
588 // Parse the 'virtual' keyword (again!), in case it came after the
589 // access specifier.
590 if (Tok.is(tok::kw_virtual)) {
591 SourceLocation VirtualLoc = ConsumeToken();
592 if (IsVirtual) {
593 // Complain about duplicate 'virtual'
Chris Lattner1ab3b962008-11-18 07:48:38 +0000594 Diag(VirtualLoc, diag::err_dup_virtual)
595 << SourceRange(VirtualLoc, VirtualLoc);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000596 }
597
598 IsVirtual = true;
599 }
600
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000601 // Parse optional '::' and optional nested-name-specifier.
602 CXXScopeSpec SS;
Chris Lattner7a0ab5f2009-01-06 06:59:53 +0000603 ParseOptionalCXXScopeSpecifier(SS);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000604
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000605 // The location of the base class itself.
606 SourceLocation BaseLoc = Tok.getLocation();
Douglas Gregor42a552f2008-11-05 20:51:48 +0000607
608 // Parse the class-name.
Douglas Gregor7f43d672009-02-25 23:52:28 +0000609 SourceLocation EndLocation;
610 TypeTy *BaseType = ParseClassName(EndLocation, &SS);
Douglas Gregor42a552f2008-11-05 20:51:48 +0000611 if (!BaseType)
612 return true;
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000613
614 // Find the complete source range for the base-specifier.
Douglas Gregor7f43d672009-02-25 23:52:28 +0000615 SourceRange Range(StartLoc, EndLocation);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000616
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000617 // Notify semantic analysis that we have parsed a complete
618 // base-specifier.
Sebastian Redla55e52c2008-11-25 22:21:31 +0000619 return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
620 BaseType, BaseLoc);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000621}
622
623/// getAccessSpecifierIfPresent - Determine whether the next token is
624/// a C++ access-specifier.
625///
626/// access-specifier: [C++ class.derived]
627/// 'private'
628/// 'protected'
629/// 'public'
Douglas Gregor1b7f8982008-04-14 00:13:42 +0000630AccessSpecifier Parser::getAccessSpecifierIfPresent() const
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000631{
632 switch (Tok.getKind()) {
633 default: return AS_none;
634 case tok::kw_private: return AS_private;
635 case tok::kw_protected: return AS_protected;
636 case tok::kw_public: return AS_public;
637 }
638}
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000639
640/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
641///
642/// member-declaration:
643/// decl-specifier-seq[opt] member-declarator-list[opt] ';'
644/// function-definition ';'[opt]
645/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
646/// using-declaration [TODO]
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000647/// [C++0x] static_assert-declaration
Anders Carlsson5aeccdb2009-03-26 00:52:18 +0000648/// template-declaration
Chris Lattnerbc8d5642008-12-18 01:12:00 +0000649/// [GNU] '__extension__' member-declaration
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000650///
651/// member-declarator-list:
652/// member-declarator
653/// member-declarator-list ',' member-declarator
654///
655/// member-declarator:
656/// declarator pure-specifier[opt]
657/// declarator constant-initializer[opt]
658/// identifier[opt] ':' constant-expression
659///
660/// pure-specifier: [TODO]
661/// '= 0'
662///
663/// constant-initializer:
664/// '=' constant-expression
665///
Chris Lattnerb28317a2009-03-28 19:18:32 +0000666Parser::DeclPtrTy Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000667 // static_assert-declaration
668 if (Tok.is(tok::kw_static_assert))
669 return ParseStaticAssertDeclaration();
670
Anders Carlsson5aeccdb2009-03-26 00:52:18 +0000671 if (Tok.is(tok::kw_template))
672 return ParseTemplateDeclarationOrSpecialization(Declarator::MemberContext,
673 AS);
674
Chris Lattnerbc8d5642008-12-18 01:12:00 +0000675 // Handle: member-declaration ::= '__extension__' member-declaration
676 if (Tok.is(tok::kw___extension__)) {
677 // __extension__ silences extension warnings in the subexpression.
678 ExtensionRAIIObject O(Diags); // Use RAII to do this.
679 ConsumeToken();
680 return ParseCXXClassMemberDeclaration(AS);
681 }
682
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000683 SourceLocation DSStart = Tok.getLocation();
684 // decl-specifier-seq:
685 // Parse the common declaration-specifiers piece.
686 DeclSpec DS;
Douglas Gregor06c0fec2009-03-25 22:00:53 +0000687 ParseDeclarationSpecifiers(DS, 0, AS);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000688
689 if (Tok.is(tok::semi)) {
690 ConsumeToken();
691 // C++ 9.2p7: The member-declarator-list can be omitted only after a
692 // class-specifier or an enum-specifier or in a friend declaration.
693 // FIXME: Friend declarations.
694 switch (DS.getTypeSpecType()) {
695 case DeclSpec::TST_struct:
696 case DeclSpec::TST_union:
697 case DeclSpec::TST_class:
698 case DeclSpec::TST_enum:
699 return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
700 default:
701 Diag(DSStart, diag::err_no_declarators);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000702 return DeclPtrTy();
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000703 }
704 }
Argyrios Kyrtzidis07952322008-07-01 10:37:29 +0000705
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000706 Declarator DeclaratorInfo(DS, Declarator::MemberContext);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000707
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000708 if (Tok.isNot(tok::colon)) {
709 // Parse the first declarator.
710 ParseDeclarator(DeclaratorInfo);
711 // Error parsing the declarator?
Douglas Gregor10bd3682008-11-17 22:58:34 +0000712 if (!DeclaratorInfo.hasName()) {
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000713 // If so, skip until the semi-colon or a }.
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000714 SkipUntil(tok::r_brace, true);
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000715 if (Tok.is(tok::semi))
716 ConsumeToken();
Chris Lattnerb28317a2009-03-28 19:18:32 +0000717 return DeclPtrTy();
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000718 }
719
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000720 // function-definition:
Douglas Gregor7ad83902008-11-05 04:29:56 +0000721 if (Tok.is(tok::l_brace)
722 || (DeclaratorInfo.isFunctionDeclarator() && Tok.is(tok::colon))) {
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000723 if (!DeclaratorInfo.isFunctionDeclarator()) {
724 Diag(Tok, diag::err_func_def_no_params);
725 ConsumeBrace();
726 SkipUntil(tok::r_brace, true);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000727 return DeclPtrTy();
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000728 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000729
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000730 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
731 Diag(Tok, diag::err_function_declared_typedef);
732 // This recovery skips the entire function body. It would be nice
733 // to simply call ParseCXXInlineMethodDef() below, however Sema
734 // assumes the declarator represents a function, not a typedef.
735 ConsumeBrace();
736 SkipUntil(tok::r_brace, true);
Chris Lattnerb28317a2009-03-28 19:18:32 +0000737 return DeclPtrTy();
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000738 }
739
740 return ParseCXXInlineMethodDef(AS, DeclaratorInfo);
741 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000742 }
743
744 // member-declarator-list:
745 // member-declarator
746 // member-declarator-list ',' member-declarator
747
Chris Lattnerb28317a2009-03-28 19:18:32 +0000748 DeclPtrTy LastDeclInGroup;
Sebastian Redl15faa7f2008-12-09 20:22:58 +0000749 OwningExprResult BitfieldSize(Actions);
750 OwningExprResult Init(Actions);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000751
752 while (1) {
753
754 // member-declarator:
755 // declarator pure-specifier[opt]
756 // declarator constant-initializer[opt]
757 // identifier[opt] ':' constant-expression
758
759 if (Tok.is(tok::colon)) {
760 ConsumeToken();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000761 BitfieldSize = ParseConstantExpression();
762 if (BitfieldSize.isInvalid())
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000763 SkipUntil(tok::comma, true, true);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000764 }
765
766 // pure-specifier:
767 // '= 0'
768 //
769 // constant-initializer:
770 // '=' constant-expression
771
772 if (Tok.is(tok::equal)) {
773 ConsumeToken();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000774 Init = ParseInitializer();
775 if (Init.isInvalid())
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000776 SkipUntil(tok::comma, true, true);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000777 }
778
779 // If attributes exist after the declarator, parse them.
Sebastian Redlab197ba2009-02-09 18:23:29 +0000780 if (Tok.is(tok::kw___attribute)) {
781 SourceLocation Loc;
782 AttributeList *AttrList = ParseAttributes(&Loc);
783 DeclaratorInfo.AddAttributes(AttrList, Loc);
784 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000785
Argyrios Kyrtzidis07952322008-07-01 10:37:29 +0000786 // NOTE: If Sema is the Action module and declarator is an instance field,
787 // this call will *not* return the created decl; LastDeclInGroup will be
788 // returned instead.
789 // See Sema::ActOnCXXMemberDeclarator for details.
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000790 LastDeclInGroup = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
791 DeclaratorInfo,
Sebastian Redleffa8d12008-12-10 00:02:53 +0000792 BitfieldSize.release(),
793 Init.release(),
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000794 LastDeclInGroup);
795
Douglas Gregor72b505b2008-12-16 21:30:33 +0000796 if (DeclaratorInfo.isFunctionDeclarator() &&
797 DeclaratorInfo.getDeclSpec().getStorageClassSpec()
798 != DeclSpec::SCS_typedef) {
799 // We just declared a member function. If this member function
800 // has any default arguments, we'll need to parse them later.
801 LateParsedMethodDeclaration *LateMethod = 0;
802 DeclaratorChunk::FunctionTypeInfo &FTI
803 = DeclaratorInfo.getTypeObject(0).Fun;
804 for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
805 if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
806 if (!LateMethod) {
807 // Push this method onto the stack of late-parsed method
808 // declarations.
809 getCurTopClassStack().MethodDecls.push_back(
810 LateParsedMethodDeclaration(LastDeclInGroup));
811 LateMethod = &getCurTopClassStack().MethodDecls.back();
812
813 // Add all of the parameters prior to this one (they don't
814 // have default arguments).
815 LateMethod->DefaultArgs.reserve(FTI.NumArgs);
816 for (unsigned I = 0; I < ParamIdx; ++I)
817 LateMethod->DefaultArgs.push_back(
818 LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param));
819 }
820
821 // Add this parameter to the list of parameters (it or may
822 // not have a default argument).
823 LateMethod->DefaultArgs.push_back(
824 LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
825 FTI.ArgInfo[ParamIdx].DefaultArgTokens));
826 }
827 }
828 }
829
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000830 // If we don't have a comma, it is either the end of the list (a ';')
831 // or an error, bail out.
832 if (Tok.isNot(tok::comma))
833 break;
834
835 // Consume the comma.
836 ConsumeToken();
837
838 // Parse the next declarator.
839 DeclaratorInfo.clear();
Sebastian Redl15faa7f2008-12-09 20:22:58 +0000840 BitfieldSize = 0;
841 Init = 0;
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000842
843 // Attributes are only allowed on the second declarator.
Sebastian Redlab197ba2009-02-09 18:23:29 +0000844 if (Tok.is(tok::kw___attribute)) {
845 SourceLocation Loc;
846 AttributeList *AttrList = ParseAttributes(&Loc);
847 DeclaratorInfo.AddAttributes(AttrList, Loc);
848 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000849
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000850 if (Tok.isNot(tok::colon))
851 ParseDeclarator(DeclaratorInfo);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000852 }
853
854 if (Tok.is(tok::semi)) {
855 ConsumeToken();
856 // Reverse the chain list.
857 return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup);
858 }
859
860 Diag(Tok, diag::err_expected_semi_decl_list);
861 // Skip to end of block or statement
862 SkipUntil(tok::r_brace, true, true);
863 if (Tok.is(tok::semi))
864 ConsumeToken();
Chris Lattnerb28317a2009-03-28 19:18:32 +0000865 return DeclPtrTy();
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000866}
867
868/// ParseCXXMemberSpecification - Parse the class definition.
869///
870/// member-specification:
871/// member-declaration member-specification[opt]
872/// access-specifier ':' member-specification[opt]
873///
874void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
Chris Lattnerb28317a2009-03-28 19:18:32 +0000875 unsigned TagType, DeclPtrTy TagDecl) {
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000876 assert((TagType == DeclSpec::TST_struct ||
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000877 TagType == DeclSpec::TST_union ||
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000878 TagType == DeclSpec::TST_class) && "Invalid TagType!");
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000879
Chris Lattner49f28ca2009-03-05 08:00:35 +0000880 PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
881 PP.getSourceManager(),
882 "parsing struct/union/class body");
Chris Lattner27b7f102009-03-05 02:25:03 +0000883
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000884 SourceLocation LBraceLoc = ConsumeBrace();
885
Douglas Gregor3218c4b2009-01-09 22:42:13 +0000886 if (!CurScope->isClassScope() && // Not about to define a nested class.
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000887 CurScope->isInCXXInlineMethodScope()) {
888 // We will define a local class of an inline method.
889 // Push a new LexedMethodsForTopClass for its inline methods.
890 PushTopClassStack();
891 }
892
893 // Enter a scope for the class.
Douglas Gregor3218c4b2009-01-09 22:42:13 +0000894 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000895
Douglas Gregorddc29e12009-02-06 22:42:48 +0000896 if (TagDecl)
897 Actions.ActOnTagStartDefinition(CurScope, TagDecl);
898 else {
899 SkipUntil(tok::r_brace, false, false);
900 return;
901 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000902
903 // C++ 11p3: Members of a class defined with the keyword class are private
904 // by default. Members of a class defined with the keywords struct or union
905 // are public by default.
906 AccessSpecifier CurAS;
907 if (TagType == DeclSpec::TST_class)
908 CurAS = AS_private;
909 else
910 CurAS = AS_public;
911
912 // While we still have something to read, read the member-declarations.
913 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
914 // Each iteration of this loop reads one member-declaration.
915
916 // Check for extraneous top-level semicolon.
917 if (Tok.is(tok::semi)) {
918 Diag(Tok, diag::ext_extra_struct_semi);
919 ConsumeToken();
920 continue;
921 }
922
923 AccessSpecifier AS = getAccessSpecifierIfPresent();
924 if (AS != AS_none) {
925 // Current token is a C++ access specifier.
926 CurAS = AS;
927 ConsumeToken();
928 ExpectAndConsume(tok::colon, diag::err_expected_colon);
929 continue;
930 }
931
932 // Parse all the comma separated declarators.
933 ParseCXXClassMemberDeclaration(CurAS);
934 }
935
936 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
937
938 AttributeList *AttrList = 0;
939 // If attributes exist after class contents, parse them.
940 if (Tok.is(tok::kw___attribute))
941 AttrList = ParseAttributes(); // FIXME: where should I put them?
942
943 Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl,
944 LBraceLoc, RBraceLoc);
945
946 // C++ 9.2p2: Within the class member-specification, the class is regarded as
947 // complete within function bodies, default arguments,
948 // exception-specifications, and constructor ctor-initializers (including
949 // such things in nested classes).
950 //
Douglas Gregor72b505b2008-12-16 21:30:33 +0000951 // FIXME: Only function bodies and constructor ctor-initializers are
952 // parsed correctly, fix the rest.
Douglas Gregor3218c4b2009-01-09 22:42:13 +0000953 if (!CurScope->getParent()->isClassScope()) {
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000954 // We are not inside a nested class. This class and its nested classes
Douglas Gregor72b505b2008-12-16 21:30:33 +0000955 // are complete and we can parse the delayed portions of method
956 // declarations and the lexed inline method definitions.
957 ParseLexedMethodDeclarations();
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000958 ParseLexedMethodDefs();
959
960 // For a local class of inline method, pop the LexedMethodsForTopClass that
961 // was previously pushed.
962
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000963 assert((CurScope->isInCXXInlineMethodScope() ||
964 TopClassStacks.size() == 1) &&
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000965 "MethodLexers not getting popped properly!");
966 if (CurScope->isInCXXInlineMethodScope())
967 PopTopClassStack();
968 }
969
970 // Leave the class scope.
Douglas Gregor8935b8b2008-12-10 06:34:36 +0000971 ClassScope.Exit();
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000972
Douglas Gregor72de6672009-01-08 20:45:30 +0000973 Actions.ActOnTagFinishDefinition(CurScope, TagDecl);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000974}
Douglas Gregor7ad83902008-11-05 04:29:56 +0000975
976/// ParseConstructorInitializer - Parse a C++ constructor initializer,
977/// which explicitly initializes the members or base classes of a
978/// class (C++ [class.base.init]). For example, the three initializers
979/// after the ':' in the Derived constructor below:
980///
981/// @code
982/// class Base { };
983/// class Derived : Base {
984/// int x;
985/// float f;
986/// public:
987/// Derived(float f) : Base(), x(17), f(f) { }
988/// };
989/// @endcode
990///
991/// [C++] ctor-initializer:
992/// ':' mem-initializer-list
993///
994/// [C++] mem-initializer-list:
995/// mem-initializer
996/// mem-initializer , mem-initializer-list
Chris Lattnerb28317a2009-03-28 19:18:32 +0000997void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) {
Douglas Gregor7ad83902008-11-05 04:29:56 +0000998 assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
999
1000 SourceLocation ColonLoc = ConsumeToken();
1001
1002 llvm::SmallVector<MemInitTy*, 4> MemInitializers;
1003
1004 do {
1005 MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
Douglas Gregor5ac8aff2009-01-26 22:44:13 +00001006 if (!MemInit.isInvalid())
1007 MemInitializers.push_back(MemInit.get());
Douglas Gregor7ad83902008-11-05 04:29:56 +00001008
1009 if (Tok.is(tok::comma))
1010 ConsumeToken();
1011 else if (Tok.is(tok::l_brace))
1012 break;
1013 else {
1014 // Skip over garbage, until we get to '{'. Don't eat the '{'.
1015 SkipUntil(tok::l_brace, true, true);
1016 break;
1017 }
1018 } while (true);
1019
1020 Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc,
1021 &MemInitializers[0], MemInitializers.size());
1022}
1023
1024/// ParseMemInitializer - Parse a C++ member initializer, which is
1025/// part of a constructor initializer that explicitly initializes one
1026/// member or base class (C++ [class.base.init]). See
1027/// ParseConstructorInitializer for an example.
1028///
1029/// [C++] mem-initializer:
1030/// mem-initializer-id '(' expression-list[opt] ')'
1031///
1032/// [C++] mem-initializer-id:
1033/// '::'[opt] nested-name-specifier[opt] class-name
1034/// identifier
Chris Lattnerb28317a2009-03-28 19:18:32 +00001035Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
Douglas Gregor7ad83902008-11-05 04:29:56 +00001036 // FIXME: parse '::'[opt] nested-name-specifier[opt]
1037
1038 if (Tok.isNot(tok::identifier)) {
Chris Lattner1ab3b962008-11-18 07:48:38 +00001039 Diag(Tok, diag::err_expected_member_or_base_name);
Douglas Gregor7ad83902008-11-05 04:29:56 +00001040 return true;
1041 }
1042
1043 // Get the identifier. This may be a member name or a class name,
1044 // but we'll let the semantic analysis determine which it is.
1045 IdentifierInfo *II = Tok.getIdentifierInfo();
1046 SourceLocation IdLoc = ConsumeToken();
1047
1048 // Parse the '('.
1049 if (Tok.isNot(tok::l_paren)) {
Chris Lattner1ab3b962008-11-18 07:48:38 +00001050 Diag(Tok, diag::err_expected_lparen);
Douglas Gregor7ad83902008-11-05 04:29:56 +00001051 return true;
1052 }
1053 SourceLocation LParenLoc = ConsumeParen();
1054
1055 // Parse the optional expression-list.
Sebastian Redla55e52c2008-11-25 22:21:31 +00001056 ExprVector ArgExprs(Actions);
Douglas Gregor7ad83902008-11-05 04:29:56 +00001057 CommaLocsTy CommaLocs;
1058 if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
1059 SkipUntil(tok::r_paren);
1060 return true;
1061 }
1062
1063 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1064
Sebastian Redla55e52c2008-11-25 22:21:31 +00001065 return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, II, IdLoc,
1066 LParenLoc, ArgExprs.take(),
1067 ArgExprs.size(), &CommaLocs[0], RParenLoc);
Douglas Gregor7ad83902008-11-05 04:29:56 +00001068}
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001069
1070/// ParseExceptionSpecification - Parse a C++ exception-specification
1071/// (C++ [except.spec]).
1072///
Douglas Gregora4745612008-12-01 18:00:20 +00001073/// exception-specification:
1074/// 'throw' '(' type-id-list [opt] ')'
1075/// [MS] 'throw' '(' '...' ')'
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001076///
Douglas Gregora4745612008-12-01 18:00:20 +00001077/// type-id-list:
1078/// type-id
1079/// type-id-list ',' type-id
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001080///
Sebastian Redlab197ba2009-02-09 18:23:29 +00001081bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc) {
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001082 assert(Tok.is(tok::kw_throw) && "expected throw");
1083
1084 SourceLocation ThrowLoc = ConsumeToken();
1085
1086 if (!Tok.is(tok::l_paren)) {
1087 return Diag(Tok, diag::err_expected_lparen_after) << "throw";
1088 }
1089 SourceLocation LParenLoc = ConsumeParen();
1090
Douglas Gregora4745612008-12-01 18:00:20 +00001091 // Parse throw(...), a Microsoft extension that means "this function
1092 // can throw anything".
1093 if (Tok.is(tok::ellipsis)) {
1094 SourceLocation EllipsisLoc = ConsumeToken();
1095 if (!getLang().Microsoft)
1096 Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
Sebastian Redlab197ba2009-02-09 18:23:29 +00001097 EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Douglas Gregora4745612008-12-01 18:00:20 +00001098 return false;
1099 }
1100
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001101 // Parse the sequence of type-ids.
1102 while (Tok.isNot(tok::r_paren)) {
1103 ParseTypeName();
1104 if (Tok.is(tok::comma))
1105 ConsumeToken();
1106 else
1107 break;
1108 }
1109
Sebastian Redlab197ba2009-02-09 18:23:29 +00001110 EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001111 return false;
1112}