blob: 1cf4a8fe5fdc8f62a6f77ac94d0b091cc6a803c1 [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 Gregor31a19b62009-04-01 21:51:26 +0000304Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
305 const CXXScopeSpec *SS) {
Douglas Gregor7f43d672009-02-25 23:52:28 +0000306 // 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());
Douglas Gregorc45c2322009-03-31 00:43:58 +0000310 if (TemplateId->Kind == TNK_Type_template) {
Douglas Gregor31a19b62009-04-01 21:51:26 +0000311 AnnotateTemplateIdTokenAsType(SS);
Douglas Gregor7f43d672009-02-25 23:52:28 +0000312
313 assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
314 TypeTy *Type = Tok.getAnnotationValue();
315 EndLocation = Tok.getAnnotationEndLoc();
316 ConsumeToken();
Douglas Gregor31a19b62009-04-01 21:51:26 +0000317
318 if (Type)
319 return Type;
320 return true;
Douglas Gregor7f43d672009-02-25 23:52:28 +0000321 }
322
323 // Fall through to produce an error below.
324 }
325
Douglas Gregor42a552f2008-11-05 20:51:48 +0000326 if (Tok.isNot(tok::identifier)) {
Chris Lattner1ab3b962008-11-18 07:48:38 +0000327 Diag(Tok, diag::err_expected_class_name);
Douglas Gregor31a19b62009-04-01 21:51:26 +0000328 return true;
Douglas Gregor42a552f2008-11-05 20:51:48 +0000329 }
330
331 // We have an identifier; check whether it is actually a type.
Douglas Gregorb696ea32009-02-04 17:00:24 +0000332 TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(),
333 Tok.getLocation(), CurScope, SS);
Douglas Gregor42a552f2008-11-05 20:51:48 +0000334 if (!Type) {
Chris Lattner1ab3b962008-11-18 07:48:38 +0000335 Diag(Tok, diag::err_expected_class_name);
Douglas Gregor31a19b62009-04-01 21:51:26 +0000336 return true;
Douglas Gregor42a552f2008-11-05 20:51:48 +0000337 }
338
339 // Consume the identifier.
Douglas Gregor7f43d672009-02-25 23:52:28 +0000340 EndLocation = ConsumeToken();
Douglas Gregor42a552f2008-11-05 20:51:48 +0000341 return Type;
342}
343
Douglas Gregore37ac4f2008-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 Gregorc4b4e7b2008-12-24 02:52:09 +0000384void Parser::ParseClassSpecifier(DeclSpec &DS,
Douglas Gregor06c0fec2009-03-25 22:00:53 +0000385 TemplateParameterLists *TemplateParams,
386 AccessSpecifier AS) {
Douglas Gregore37ac4f2008-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 Narofff59e17e2008-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
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000407 // Parse the (optional) nested-name-specifier.
408 CXXScopeSpec SS;
Douglas Gregor39a8de12009-02-25 19:37:18 +0000409 if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS))
410 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000411 Diag(Tok, diag::err_expected_ident);
Douglas Gregorcc636682009-02-17 23:15:12 +0000412
413 // Parse the (optional) class name or simple-template-id.
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000414 IdentifierInfo *Name = 0;
415 SourceLocation NameLoc;
Douglas Gregor39a8de12009-02-25 19:37:18 +0000416 TemplateIdAnnotation *TemplateId = 0;
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000417 if (Tok.is(tok::identifier)) {
418 Name = Tok.getIdentifierInfo();
419 NameLoc = ConsumeToken();
Douglas Gregor39a8de12009-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 Gregorcc636682009-02-17 23:15:12 +0000423
Douglas Gregorc45c2322009-03-31 00:43:58 +0000424 if (TemplateId->Kind != TNK_Type_template) {
Douglas Gregor39a8de12009-02-25 19:37:18 +0000425 // 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 Gregorcc636682009-02-17 23:15:12 +0000431
Douglas Gregor39a8de12009-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 Gregorcc636682009-02-17 23:15:12 +0000434
Douglas Gregor39a8de12009-02-25 19:37:18 +0000435 DS.SetTypeSpecError();
436 SkipUntil(tok::semi, false, true);
437 TemplateId->Destroy();
438 return;
Douglas Gregorcc636682009-02-17 23:15:12 +0000439 }
Douglas Gregore37ac4f2008-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 Gregor39a8de12009-02-25 19:37:18 +0000444 // 'struct foo :...' then this is a definition. Otherwise we have
Douglas Gregore37ac4f2008-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 Gregor39a8de12009-02-25 19:37:18 +0000454 if (!Name && !TemplateId && TK != Action::TK_Definition) {
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000455 // We have a declaration or reference to an anonymous class.
Chris Lattner1ab3b962008-11-18 07:48:38 +0000456 Diag(StartLoc, diag::err_anon_type_definition)
457 << DeclSpec::getSpecifierName(TagType);
Douglas Gregore37ac4f2008-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 Gregor39a8de12009-02-25 19:37:18 +0000461
462 if (TemplateId)
463 TemplateId->Destroy();
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000464 return;
465 }
466
Douglas Gregorddc29e12009-02-06 22:42:48 +0000467 // Create the tag portion of the class or class template.
Douglas Gregor212e81c2009-03-25 00:13:59 +0000468 Action::DeclResult TagOrTempResult;
Douglas Gregor39a8de12009-02-25 19:37:18 +0000469 if (TemplateId && TK != Action::TK_Reference) {
Douglas Gregorcc636682009-02-17 23:15:12 +0000470 // Explicit specialization or class template partial
471 // specialization. Let semantic analysis decide.
Douglas Gregor39a8de12009-02-25 19:37:18 +0000472 ASTTemplateArgsPtr TemplateArgsPtr(Actions,
473 TemplateId->getTemplateArgs(),
474 TemplateId->getTemplateArgIsType(),
475 TemplateId->NumArgs);
Douglas Gregor212e81c2009-03-25 00:13:59 +0000476 TagOrTempResult
Douglas Gregorcc636682009-02-17 23:15:12 +0000477 = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TK,
Douglas Gregor39a8de12009-02-25 19:37:18 +0000478 StartLoc, SS,
Douglas Gregor7532dc62009-03-30 22:58:21 +0000479 TemplateTy::make(TemplateId->Template),
Douglas Gregor39a8de12009-02-25 19:37:18 +0000480 TemplateId->TemplateNameLoc,
481 TemplateId->LAngleLoc,
482 TemplateArgsPtr,
483 TemplateId->getTemplateArgLocations(),
484 TemplateId->RAngleLoc,
485 Attr,
Douglas Gregorcc636682009-02-17 23:15:12 +0000486 Action::MultiTemplateParamsArg(Actions,
487 TemplateParams? &(*TemplateParams)[0] : 0,
488 TemplateParams? TemplateParams->size() : 0));
Douglas Gregor39a8de12009-02-25 19:37:18 +0000489 TemplateId->Destroy();
490 } else if (TemplateParams && TK != Action::TK_Reference)
Douglas Gregor212e81c2009-03-25 00:13:59 +0000491 TagOrTempResult = Actions.ActOnClassTemplate(CurScope, TagType, TK,
492 StartLoc, SS, Name, NameLoc,
493 Attr,
Douglas Gregorddc29e12009-02-06 22:42:48 +0000494 Action::MultiTemplateParamsArg(Actions,
495 &(*TemplateParams)[0],
Anders Carlsson5aeccdb2009-03-26 00:52:18 +0000496 TemplateParams->size()),
497 AS);
Douglas Gregorddc29e12009-02-06 22:42:48 +0000498 else
Douglas Gregor212e81c2009-03-25 00:13:59 +0000499 TagOrTempResult = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS, Name,
Douglas Gregor06c0fec2009-03-25 22:00:53 +0000500 NameLoc, Attr, AS);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000501
502 // Parse the optional base clause (C++ only).
Chris Lattner22bd9052009-02-16 22:07:16 +0000503 if (getLang().CPlusPlus && Tok.is(tok::colon))
Douglas Gregor212e81c2009-03-25 00:13:59 +0000504 ParseBaseClause(TagOrTempResult.get());
Douglas Gregore37ac4f2008-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))
Argyrios Kyrtzidis07952322008-07-01 10:37:29 +0000508 if (getLang().CPlusPlus)
Douglas Gregor212e81c2009-03-25 00:13:59 +0000509 ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
Argyrios Kyrtzidis07952322008-07-01 10:37:29 +0000510 else
Douglas Gregor212e81c2009-03-25 00:13:59 +0000511 ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
Douglas Gregore37ac4f2008-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 Lattner1ab3b962008-11-18 07:48:38 +0000515 Diag(Tok, diag::err_expected_lbrace);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000516 }
517
518 const char *PrevSpec = 0;
Douglas Gregor212e81c2009-03-25 00:13:59 +0000519 if (TagOrTempResult.isInvalid())
Douglas Gregorddc29e12009-02-06 22:42:48 +0000520 DS.SetTypeSpecError();
Douglas Gregor212e81c2009-03-25 00:13:59 +0000521 else if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec,
Chris Lattnerb28317a2009-03-28 19:18:32 +0000522 TagOrTempResult.get().getAs<void>()))
Chris Lattner1ab3b962008-11-18 07:48:38 +0000523 Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
Douglas Gregore37ac4f2008-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 Lattnerb28317a2009-03-28 19:18:32 +0000533void Parser::ParseBaseClause(DeclPtrTy ClassDecl) {
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000534 assert(Tok.is(tok::colon) && "Not a base clause");
535 ConsumeToken();
536
Douglas Gregorf8268ae2008-10-22 17:49:05 +0000537 // Build up an array of parsed base specifiers.
538 llvm::SmallVector<BaseTy *, 8> BaseInfo;
539
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000540 while (true) {
541 // Parse a base-specifier.
Douglas Gregorf8268ae2008-10-22 17:49:05 +0000542 BaseResult Result = ParseBaseSpecifier(ClassDecl);
Douglas Gregor5ac8aff2009-01-26 22:44:13 +0000543 if (Result.isInvalid()) {
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000544 // Skip the rest of this base specifier, up until the comma or
545 // opening brace.
Douglas Gregorf8268ae2008-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 Gregor5ac8aff2009-01-26 22:44:13 +0000549 BaseInfo.push_back(Result.get());
Douglas Gregore37ac4f2008-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 Gregorf8268ae2008-10-22 17:49:05 +0000559
560 // Attach the base specifiers
561 Actions.ActOnBaseSpecifiers(ClassDecl, &BaseInfo[0], BaseInfo.size());
Douglas Gregore37ac4f2008-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 Lattnerb28317a2009-03-28 19:18:32 +0000575Parser::BaseResult Parser::ParseBaseSpecifier(DeclPtrTy ClassDecl) {
Douglas Gregore37ac4f2008-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 Lattner1ab3b962008-11-18 07:48:38 +0000596 Diag(VirtualLoc, diag::err_dup_virtual)
Douglas Gregor31a19b62009-04-01 21:51:26 +0000597 << CodeModificationHint::CreateRemoval(SourceRange(VirtualLoc));
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000598 }
599
600 IsVirtual = true;
601 }
602
Argyrios Kyrtzidiseb83ecd2008-11-08 16:45:02 +0000603 // Parse optional '::' and optional nested-name-specifier.
604 CXXScopeSpec SS;
Chris Lattner7a0ab5f2009-01-06 06:59:53 +0000605 ParseOptionalCXXScopeSpecifier(SS);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000606
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000607 // The location of the base class itself.
608 SourceLocation BaseLoc = Tok.getLocation();
Douglas Gregor42a552f2008-11-05 20:51:48 +0000609
610 // Parse the class-name.
Douglas Gregor7f43d672009-02-25 23:52:28 +0000611 SourceLocation EndLocation;
Douglas Gregor31a19b62009-04-01 21:51:26 +0000612 TypeResult BaseType = ParseClassName(EndLocation, &SS);
613 if (BaseType.isInvalid())
Douglas Gregor42a552f2008-11-05 20:51:48 +0000614 return true;
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000615
616 // Find the complete source range for the base-specifier.
Douglas Gregor7f43d672009-02-25 23:52:28 +0000617 SourceRange Range(StartLoc, EndLocation);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000618
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000619 // Notify semantic analysis that we have parsed a complete
620 // base-specifier.
Sebastian Redla55e52c2008-11-25 22:21:31 +0000621 return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
Douglas Gregor31a19b62009-04-01 21:51:26 +0000622 BaseType.get(), BaseLoc);
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000623}
624
625/// getAccessSpecifierIfPresent - Determine whether the next token is
626/// a C++ access-specifier.
627///
628/// access-specifier: [C++ class.derived]
629/// 'private'
630/// 'protected'
631/// 'public'
Douglas Gregor1b7f8982008-04-14 00:13:42 +0000632AccessSpecifier Parser::getAccessSpecifierIfPresent() const
Douglas Gregore37ac4f2008-04-13 21:30:24 +0000633{
634 switch (Tok.getKind()) {
635 default: return AS_none;
636 case tok::kw_private: return AS_private;
637 case tok::kw_protected: return AS_protected;
638 case tok::kw_public: return AS_public;
639 }
640}
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000641
642/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
643///
644/// member-declaration:
645/// decl-specifier-seq[opt] member-declarator-list[opt] ';'
646/// function-definition ';'[opt]
647/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
648/// using-declaration [TODO]
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000649/// [C++0x] static_assert-declaration
Anders Carlsson5aeccdb2009-03-26 00:52:18 +0000650/// template-declaration
Chris Lattnerbc8d5642008-12-18 01:12:00 +0000651/// [GNU] '__extension__' member-declaration
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000652///
653/// member-declarator-list:
654/// member-declarator
655/// member-declarator-list ',' member-declarator
656///
657/// member-declarator:
658/// declarator pure-specifier[opt]
659/// declarator constant-initializer[opt]
660/// identifier[opt] ':' constant-expression
661///
662/// pure-specifier: [TODO]
663/// '= 0'
664///
665/// constant-initializer:
666/// '=' constant-expression
667///
Chris Lattner682bf922009-03-29 16:50:03 +0000668void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000669 // static_assert-declaration
Chris Lattner682bf922009-03-29 16:50:03 +0000670 if (Tok.is(tok::kw_static_assert)) {
671 ParseStaticAssertDeclaration();
672 return;
673 }
Anders Carlsson511d7ab2009-03-11 16:27:10 +0000674
Chris Lattner682bf922009-03-29 16:50:03 +0000675 if (Tok.is(tok::kw_template)) {
676 ParseTemplateDeclarationOrSpecialization(Declarator::MemberContext, AS);
677 return;
678 }
Anders Carlsson5aeccdb2009-03-26 00:52:18 +0000679
Chris Lattnerbc8d5642008-12-18 01:12:00 +0000680 // Handle: member-declaration ::= '__extension__' member-declaration
681 if (Tok.is(tok::kw___extension__)) {
682 // __extension__ silences extension warnings in the subexpression.
683 ExtensionRAIIObject O(Diags); // Use RAII to do this.
684 ConsumeToken();
685 return ParseCXXClassMemberDeclaration(AS);
686 }
687
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000688 SourceLocation DSStart = Tok.getLocation();
689 // decl-specifier-seq:
690 // Parse the common declaration-specifiers piece.
691 DeclSpec DS;
Douglas Gregor06c0fec2009-03-25 22:00:53 +0000692 ParseDeclarationSpecifiers(DS, 0, AS);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000693
694 if (Tok.is(tok::semi)) {
695 ConsumeToken();
696 // C++ 9.2p7: The member-declarator-list can be omitted only after a
697 // class-specifier or an enum-specifier or in a friend declaration.
698 // FIXME: Friend declarations.
699 switch (DS.getTypeSpecType()) {
Chris Lattner682bf922009-03-29 16:50:03 +0000700 case DeclSpec::TST_struct:
701 case DeclSpec::TST_union:
702 case DeclSpec::TST_class:
703 case DeclSpec::TST_enum:
704 Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
705 return;
706 default:
707 Diag(DSStart, diag::err_no_declarators);
708 return;
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000709 }
710 }
Argyrios Kyrtzidis07952322008-07-01 10:37:29 +0000711
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000712 Declarator DeclaratorInfo(DS, Declarator::MemberContext);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000713
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000714 if (Tok.isNot(tok::colon)) {
715 // Parse the first declarator.
716 ParseDeclarator(DeclaratorInfo);
717 // Error parsing the declarator?
Douglas Gregor10bd3682008-11-17 22:58:34 +0000718 if (!DeclaratorInfo.hasName()) {
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000719 // If so, skip until the semi-colon or a }.
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000720 SkipUntil(tok::r_brace, true);
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000721 if (Tok.is(tok::semi))
722 ConsumeToken();
Chris Lattner682bf922009-03-29 16:50:03 +0000723 return;
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000724 }
725
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000726 // function-definition:
Douglas Gregor7ad83902008-11-05 04:29:56 +0000727 if (Tok.is(tok::l_brace)
728 || (DeclaratorInfo.isFunctionDeclarator() && Tok.is(tok::colon))) {
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000729 if (!DeclaratorInfo.isFunctionDeclarator()) {
730 Diag(Tok, diag::err_func_def_no_params);
731 ConsumeBrace();
732 SkipUntil(tok::r_brace, true);
Chris Lattner682bf922009-03-29 16:50:03 +0000733 return;
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000734 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000735
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000736 if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
737 Diag(Tok, diag::err_function_declared_typedef);
738 // This recovery skips the entire function body. It would be nice
739 // to simply call ParseCXXInlineMethodDef() below, however Sema
740 // assumes the declarator represents a function, not a typedef.
741 ConsumeBrace();
742 SkipUntil(tok::r_brace, true);
Chris Lattner682bf922009-03-29 16:50:03 +0000743 return;
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000744 }
745
Chris Lattner682bf922009-03-29 16:50:03 +0000746 ParseCXXInlineMethodDef(AS, DeclaratorInfo);
747 return;
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000748 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000749 }
750
751 // member-declarator-list:
752 // member-declarator
753 // member-declarator-list ',' member-declarator
754
Chris Lattner682bf922009-03-29 16:50:03 +0000755 llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup;
Sebastian Redl15faa7f2008-12-09 20:22:58 +0000756 OwningExprResult BitfieldSize(Actions);
757 OwningExprResult Init(Actions);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000758
759 while (1) {
760
761 // member-declarator:
762 // declarator pure-specifier[opt]
763 // declarator constant-initializer[opt]
764 // identifier[opt] ':' constant-expression
765
766 if (Tok.is(tok::colon)) {
767 ConsumeToken();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000768 BitfieldSize = ParseConstantExpression();
769 if (BitfieldSize.isInvalid())
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000770 SkipUntil(tok::comma, true, true);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000771 }
772
773 // pure-specifier:
774 // '= 0'
775 //
776 // constant-initializer:
777 // '=' constant-expression
778
779 if (Tok.is(tok::equal)) {
780 ConsumeToken();
Sebastian Redl0e9eabc2008-12-09 13:15:23 +0000781 Init = ParseInitializer();
782 if (Init.isInvalid())
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000783 SkipUntil(tok::comma, true, true);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000784 }
785
786 // If attributes exist after the declarator, parse them.
Sebastian Redlab197ba2009-02-09 18:23:29 +0000787 if (Tok.is(tok::kw___attribute)) {
788 SourceLocation Loc;
789 AttributeList *AttrList = ParseAttributes(&Loc);
790 DeclaratorInfo.AddAttributes(AttrList, Loc);
791 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000792
Argyrios Kyrtzidis07952322008-07-01 10:37:29 +0000793 // NOTE: If Sema is the Action module and declarator is an instance field,
Chris Lattner682bf922009-03-29 16:50:03 +0000794 // this call will *not* return the created decl; It will return null.
Argyrios Kyrtzidis07952322008-07-01 10:37:29 +0000795 // See Sema::ActOnCXXMemberDeclarator for details.
Chris Lattner682bf922009-03-29 16:50:03 +0000796 DeclPtrTy ThisDecl = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
797 DeclaratorInfo,
798 BitfieldSize.release(),
799 Init.release());
800 if (ThisDecl)
801 DeclsInGroup.push_back(ThisDecl);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000802
Douglas Gregor72b505b2008-12-16 21:30:33 +0000803 if (DeclaratorInfo.isFunctionDeclarator() &&
804 DeclaratorInfo.getDeclSpec().getStorageClassSpec()
805 != DeclSpec::SCS_typedef) {
806 // We just declared a member function. If this member function
807 // has any default arguments, we'll need to parse them later.
808 LateParsedMethodDeclaration *LateMethod = 0;
809 DeclaratorChunk::FunctionTypeInfo &FTI
810 = DeclaratorInfo.getTypeObject(0).Fun;
811 for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
812 if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
813 if (!LateMethod) {
814 // Push this method onto the stack of late-parsed method
815 // declarations.
816 getCurTopClassStack().MethodDecls.push_back(
Chris Lattner682bf922009-03-29 16:50:03 +0000817 LateParsedMethodDeclaration(ThisDecl));
Douglas Gregor72b505b2008-12-16 21:30:33 +0000818 LateMethod = &getCurTopClassStack().MethodDecls.back();
819
820 // Add all of the parameters prior to this one (they don't
821 // have default arguments).
822 LateMethod->DefaultArgs.reserve(FTI.NumArgs);
823 for (unsigned I = 0; I < ParamIdx; ++I)
824 LateMethod->DefaultArgs.push_back(
825 LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param));
826 }
827
828 // Add this parameter to the list of parameters (it or may
829 // not have a default argument).
830 LateMethod->DefaultArgs.push_back(
831 LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
832 FTI.ArgInfo[ParamIdx].DefaultArgTokens));
833 }
834 }
835 }
836
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000837 // If we don't have a comma, it is either the end of the list (a ';')
838 // or an error, bail out.
839 if (Tok.isNot(tok::comma))
840 break;
841
842 // Consume the comma.
843 ConsumeToken();
844
845 // Parse the next declarator.
846 DeclaratorInfo.clear();
Sebastian Redl15faa7f2008-12-09 20:22:58 +0000847 BitfieldSize = 0;
848 Init = 0;
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000849
850 // Attributes are only allowed on the second declarator.
Sebastian Redlab197ba2009-02-09 18:23:29 +0000851 if (Tok.is(tok::kw___attribute)) {
852 SourceLocation Loc;
853 AttributeList *AttrList = ParseAttributes(&Loc);
854 DeclaratorInfo.AddAttributes(AttrList, Loc);
855 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000856
Argyrios Kyrtzidis3a9fdb42008-06-28 08:10:48 +0000857 if (Tok.isNot(tok::colon))
858 ParseDeclarator(DeclaratorInfo);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000859 }
860
861 if (Tok.is(tok::semi)) {
862 ConsumeToken();
Chris Lattner682bf922009-03-29 16:50:03 +0000863 Actions.FinalizeDeclaratorGroup(CurScope, &DeclsInGroup[0],
864 DeclsInGroup.size());
865 return;
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000866 }
867
868 Diag(Tok, diag::err_expected_semi_decl_list);
869 // Skip to end of block or statement
870 SkipUntil(tok::r_brace, true, true);
871 if (Tok.is(tok::semi))
872 ConsumeToken();
Chris Lattner682bf922009-03-29 16:50:03 +0000873 return;
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000874}
875
876/// ParseCXXMemberSpecification - Parse the class definition.
877///
878/// member-specification:
879/// member-declaration member-specification[opt]
880/// access-specifier ':' member-specification[opt]
881///
882void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
Chris Lattnerb28317a2009-03-28 19:18:32 +0000883 unsigned TagType, DeclPtrTy TagDecl) {
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000884 assert((TagType == DeclSpec::TST_struct ||
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000885 TagType == DeclSpec::TST_union ||
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000886 TagType == DeclSpec::TST_class) && "Invalid TagType!");
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000887
Chris Lattner49f28ca2009-03-05 08:00:35 +0000888 PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
889 PP.getSourceManager(),
890 "parsing struct/union/class body");
Chris Lattner27b7f102009-03-05 02:25:03 +0000891
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000892 SourceLocation LBraceLoc = ConsumeBrace();
893
Douglas Gregor3218c4b2009-01-09 22:42:13 +0000894 if (!CurScope->isClassScope() && // Not about to define a nested class.
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000895 CurScope->isInCXXInlineMethodScope()) {
896 // We will define a local class of an inline method.
897 // Push a new LexedMethodsForTopClass for its inline methods.
898 PushTopClassStack();
899 }
900
901 // Enter a scope for the class.
Douglas Gregor3218c4b2009-01-09 22:42:13 +0000902 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000903
Douglas Gregorddc29e12009-02-06 22:42:48 +0000904 if (TagDecl)
905 Actions.ActOnTagStartDefinition(CurScope, TagDecl);
906 else {
907 SkipUntil(tok::r_brace, false, false);
908 return;
909 }
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000910
911 // C++ 11p3: Members of a class defined with the keyword class are private
912 // by default. Members of a class defined with the keywords struct or union
913 // are public by default.
914 AccessSpecifier CurAS;
915 if (TagType == DeclSpec::TST_class)
916 CurAS = AS_private;
917 else
918 CurAS = AS_public;
919
920 // While we still have something to read, read the member-declarations.
921 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
922 // Each iteration of this loop reads one member-declaration.
923
924 // Check for extraneous top-level semicolon.
925 if (Tok.is(tok::semi)) {
926 Diag(Tok, diag::ext_extra_struct_semi);
927 ConsumeToken();
928 continue;
929 }
930
931 AccessSpecifier AS = getAccessSpecifierIfPresent();
932 if (AS != AS_none) {
933 // Current token is a C++ access specifier.
934 CurAS = AS;
935 ConsumeToken();
936 ExpectAndConsume(tok::colon, diag::err_expected_colon);
937 continue;
938 }
939
940 // Parse all the comma separated declarators.
941 ParseCXXClassMemberDeclaration(CurAS);
942 }
943
944 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
945
946 AttributeList *AttrList = 0;
947 // If attributes exist after class contents, parse them.
948 if (Tok.is(tok::kw___attribute))
949 AttrList = ParseAttributes(); // FIXME: where should I put them?
950
951 Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl,
952 LBraceLoc, RBraceLoc);
953
954 // C++ 9.2p2: Within the class member-specification, the class is regarded as
955 // complete within function bodies, default arguments,
956 // exception-specifications, and constructor ctor-initializers (including
957 // such things in nested classes).
958 //
Douglas Gregor72b505b2008-12-16 21:30:33 +0000959 // FIXME: Only function bodies and constructor ctor-initializers are
960 // parsed correctly, fix the rest.
Douglas Gregor3218c4b2009-01-09 22:42:13 +0000961 if (!CurScope->getParent()->isClassScope()) {
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000962 // We are not inside a nested class. This class and its nested classes
Douglas Gregor72b505b2008-12-16 21:30:33 +0000963 // are complete and we can parse the delayed portions of method
964 // declarations and the lexed inline method definitions.
965 ParseLexedMethodDeclarations();
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000966 ParseLexedMethodDefs();
967
968 // For a local class of inline method, pop the LexedMethodsForTopClass that
969 // was previously pushed.
970
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000971 assert((CurScope->isInCXXInlineMethodScope() ||
972 TopClassStacks.size() == 1) &&
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000973 "MethodLexers not getting popped properly!");
974 if (CurScope->isInCXXInlineMethodScope())
975 PopTopClassStack();
976 }
977
978 // Leave the class scope.
Douglas Gregor8935b8b2008-12-10 06:34:36 +0000979 ClassScope.Exit();
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000980
Douglas Gregor72de6672009-01-08 20:45:30 +0000981 Actions.ActOnTagFinishDefinition(CurScope, TagDecl);
Argyrios Kyrtzidis4cc18a42008-06-24 22:12:16 +0000982}
Douglas Gregor7ad83902008-11-05 04:29:56 +0000983
984/// ParseConstructorInitializer - Parse a C++ constructor initializer,
985/// which explicitly initializes the members or base classes of a
986/// class (C++ [class.base.init]). For example, the three initializers
987/// after the ':' in the Derived constructor below:
988///
989/// @code
990/// class Base { };
991/// class Derived : Base {
992/// int x;
993/// float f;
994/// public:
995/// Derived(float f) : Base(), x(17), f(f) { }
996/// };
997/// @endcode
998///
999/// [C++] ctor-initializer:
1000/// ':' mem-initializer-list
1001///
1002/// [C++] mem-initializer-list:
1003/// mem-initializer
1004/// mem-initializer , mem-initializer-list
Chris Lattnerb28317a2009-03-28 19:18:32 +00001005void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) {
Douglas Gregor7ad83902008-11-05 04:29:56 +00001006 assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
1007
1008 SourceLocation ColonLoc = ConsumeToken();
1009
1010 llvm::SmallVector<MemInitTy*, 4> MemInitializers;
1011
1012 do {
1013 MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
Douglas Gregor5ac8aff2009-01-26 22:44:13 +00001014 if (!MemInit.isInvalid())
1015 MemInitializers.push_back(MemInit.get());
Douglas Gregor7ad83902008-11-05 04:29:56 +00001016
1017 if (Tok.is(tok::comma))
1018 ConsumeToken();
1019 else if (Tok.is(tok::l_brace))
1020 break;
1021 else {
1022 // Skip over garbage, until we get to '{'. Don't eat the '{'.
1023 SkipUntil(tok::l_brace, true, true);
1024 break;
1025 }
1026 } while (true);
1027
1028 Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc,
1029 &MemInitializers[0], MemInitializers.size());
1030}
1031
1032/// ParseMemInitializer - Parse a C++ member initializer, which is
1033/// part of a constructor initializer that explicitly initializes one
1034/// member or base class (C++ [class.base.init]). See
1035/// ParseConstructorInitializer for an example.
1036///
1037/// [C++] mem-initializer:
1038/// mem-initializer-id '(' expression-list[opt] ')'
1039///
1040/// [C++] mem-initializer-id:
1041/// '::'[opt] nested-name-specifier[opt] class-name
1042/// identifier
Chris Lattnerb28317a2009-03-28 19:18:32 +00001043Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
Douglas Gregor7ad83902008-11-05 04:29:56 +00001044 // FIXME: parse '::'[opt] nested-name-specifier[opt]
1045
1046 if (Tok.isNot(tok::identifier)) {
Chris Lattner1ab3b962008-11-18 07:48:38 +00001047 Diag(Tok, diag::err_expected_member_or_base_name);
Douglas Gregor7ad83902008-11-05 04:29:56 +00001048 return true;
1049 }
1050
1051 // Get the identifier. This may be a member name or a class name,
1052 // but we'll let the semantic analysis determine which it is.
1053 IdentifierInfo *II = Tok.getIdentifierInfo();
1054 SourceLocation IdLoc = ConsumeToken();
1055
1056 // Parse the '('.
1057 if (Tok.isNot(tok::l_paren)) {
Chris Lattner1ab3b962008-11-18 07:48:38 +00001058 Diag(Tok, diag::err_expected_lparen);
Douglas Gregor7ad83902008-11-05 04:29:56 +00001059 return true;
1060 }
1061 SourceLocation LParenLoc = ConsumeParen();
1062
1063 // Parse the optional expression-list.
Sebastian Redla55e52c2008-11-25 22:21:31 +00001064 ExprVector ArgExprs(Actions);
Douglas Gregor7ad83902008-11-05 04:29:56 +00001065 CommaLocsTy CommaLocs;
1066 if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
1067 SkipUntil(tok::r_paren);
1068 return true;
1069 }
1070
1071 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1072
Sebastian Redla55e52c2008-11-25 22:21:31 +00001073 return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, II, IdLoc,
1074 LParenLoc, ArgExprs.take(),
1075 ArgExprs.size(), &CommaLocs[0], RParenLoc);
Douglas Gregor7ad83902008-11-05 04:29:56 +00001076}
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001077
1078/// ParseExceptionSpecification - Parse a C++ exception-specification
1079/// (C++ [except.spec]).
1080///
Douglas Gregora4745612008-12-01 18:00:20 +00001081/// exception-specification:
1082/// 'throw' '(' type-id-list [opt] ')'
1083/// [MS] 'throw' '(' '...' ')'
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001084///
Douglas Gregora4745612008-12-01 18:00:20 +00001085/// type-id-list:
1086/// type-id
1087/// type-id-list ',' type-id
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001088///
Sebastian Redlab197ba2009-02-09 18:23:29 +00001089bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc) {
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001090 assert(Tok.is(tok::kw_throw) && "expected throw");
1091
1092 SourceLocation ThrowLoc = ConsumeToken();
1093
1094 if (!Tok.is(tok::l_paren)) {
1095 return Diag(Tok, diag::err_expected_lparen_after) << "throw";
1096 }
1097 SourceLocation LParenLoc = ConsumeParen();
1098
Douglas Gregora4745612008-12-01 18:00:20 +00001099 // Parse throw(...), a Microsoft extension that means "this function
1100 // can throw anything".
1101 if (Tok.is(tok::ellipsis)) {
1102 SourceLocation EllipsisLoc = ConsumeToken();
1103 if (!getLang().Microsoft)
1104 Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
Sebastian Redlab197ba2009-02-09 18:23:29 +00001105 EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Douglas Gregora4745612008-12-01 18:00:20 +00001106 return false;
1107 }
1108
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001109 // Parse the sequence of type-ids.
1110 while (Tok.isNot(tok::r_paren)) {
1111 ParseTypeName();
1112 if (Tok.is(tok::comma))
1113 ConsumeToken();
1114 else
1115 break;
1116 }
1117
Sebastian Redlab197ba2009-02-09 18:23:29 +00001118 EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
Douglas Gregor0fe7bea2008-11-25 03:22:00 +00001119 return false;
1120}