ParseDeclCXX.cpp revision d33133cdc1af466f9c276249b2621be03867888b
18f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -----------------------===//
28f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//
38f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//                     The LLVM Compiler Infrastructure
48f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
78f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//
88f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===----------------------------------------------------------------------===//
98f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//
108f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//  This file implements the C++ Declaration portions of the Parser interfaces.
118f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//
128f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===----------------------------------------------------------------------===//
138f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner
140c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson#include "clang/Basic/OperatorKinds.h"
151b7f89846f10681ce3cbe89ef5d60691d55bd918Douglas Gregor#include "clang/Parse/Parser.h"
16500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h"
17e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor#include "clang/Parse/DeclSpec.h"
188f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner#include "clang/Parse/Scope.h"
19bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner#include "ExtensionRAIIObject.h"
208f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattnerusing namespace clang;
218f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner
228f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// ParseNamespace - We know that the current token is a namespace keyword. This
238f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// may either be a top level namespace or a block-level namespace alias.
248f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
258f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       namespace-definition: [C++ 7.3: basic.namespace]
268f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         named-namespace-definition
278f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         unnamed-namespace-definition
288f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
298f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       unnamed-namespace-definition:
308f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         'namespace' attributes[opt] '{' namespace-body '}'
318f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
328f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       named-namespace-definition:
338f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         original-namespace-definition
348f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         extension-namespace-definition
358f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
368f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       original-namespace-definition:
378f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         'namespace' identifier attributes[opt] '{' namespace-body '}'
388f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
398f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       extension-namespace-definition:
408f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         'namespace' original-namespace-name '{' namespace-body '}'
418f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
428f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       namespace-alias-definition:  [C++ 7.3.2: namespace.alias]
438f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         'namespace' identifier '=' qualified-namespace-specifier ';'
448f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
4597144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris LattnerParser::DeclPtrTy Parser::ParseNamespace(unsigned Context,
4697144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                         SourceLocation &DeclEnd) {
4704d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
488f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation NamespaceLoc = ConsumeToken();  // eat the 'namespace'.
498f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner
508f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation IdentLoc;
518f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  IdentifierInfo *Ident = 0;
526a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
536a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  Token attrTok;
548f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner
5504d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  if (Tok.is(tok::identifier)) {
568f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    Ident = Tok.getIdentifierInfo();
578f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    IdentLoc = ConsumeToken();  // eat the identifier.
588f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  }
598f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner
608f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  // Read label attributes, if present.
61b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner  Action::AttrTy *AttrList = 0;
626a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::kw___attribute)) {
636a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor    attrTok = Tok;
646a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
658f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    // FIXME: save these somewhere.
668f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    AttrList = ParseAttributes();
676a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
688f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner
696a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::equal)) {
706a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor    if (AttrList)
716a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor      Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
726a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
7397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
746a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
75f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
765144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  if (Tok.isNot(tok::l_brace)) {
775144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner    Diag(Tok, Ident ? diag::err_expected_lbrace :
785144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner         diag::err_expected_ident_lbrace);
795144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner    return DeclPtrTy();
805144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  }
815144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner
825144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  SourceLocation LBrace = ConsumeBrace();
832d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
845144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Enter a scope for the namespace.
855144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  ParseScope NamespaceScope(this, Scope::DeclScope);
862d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
875144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  DeclPtrTy NamespcDecl =
885144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner    Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace);
892d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
905144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions,
915144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner                                        PP.getSourceManager(),
925144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner                                        "parsing namespace");
935144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner
945144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof))
955144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner    ParseExternalDeclaration();
965144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner
975144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Leave the namespace scope.
985144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  NamespaceScope.Exit();
998ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis
10097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBrace);
10197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  Actions.ActOnFinishNamespaceDef(NamespcDecl, RBraceLoc);
1022d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
10397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = RBraceLoc;
1045144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  return NamespcDecl;
1058f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner}
106c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
107f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
108f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// alias definition.
109f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson///
11003bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders CarlssonParser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
11103bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson                                              SourceLocation AliasLoc,
11297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                              IdentifierInfo *Alias,
11397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                              SourceLocation &DeclEnd) {
114f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  assert(Tok.is(tok::equal) && "Not equal token");
115f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
116f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  ConsumeToken(); // eat the '='.
117f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
118f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  CXXScopeSpec SS;
119f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse (optional) nested-name-specifier.
120f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  ParseOptionalCXXScopeSpecifier(SS);
121f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
122f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
123f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    Diag(Tok, diag::err_expected_namespace_name);
124f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    // Skip to end of the definition and eat the ';'.
125f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    SkipUntil(tok::semi);
126b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
127f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  }
128f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
129f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse identifier.
13003bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  IdentifierInfo *Ident = Tok.getIdentifierInfo();
13103bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  SourceLocation IdentLoc = ConsumeToken();
132f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
133f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Eat the ';'.
13497144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
1356869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name,
1366869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner                   "", tok::semi);
137f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
13803bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  return Actions.ActOnNamespaceAliasDef(CurScope, NamespaceLoc, AliasLoc, Alias,
13903bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson                                        SS, IdentLoc, Ident);
140f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson}
141f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
142c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal
143c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen.
144c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
145c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///       linkage-specification: [C++ 7.5p2: dcl.link]
146c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal '{' declaration-seq[opt] '}'
147c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal declaration
148c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
149b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris LattnerParser::DeclPtrTy Parser::ParseLinkage(unsigned Context) {
150c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor  assert(Tok.is(tok::string_literal) && "Not a string literal!");
151c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  llvm::SmallVector<char, 8> LangBuffer;
152c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  // LangBuffer is guaranteed to be big enough.
153c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  LangBuffer.resize(Tok.getLength());
154c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  const char *LangBufPtr = &LangBuffer[0];
155c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  unsigned StrSize = PP.getSpelling(Tok, LangBufPtr);
156c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
157c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  SourceLocation Loc = ConsumeStringToken();
158c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
159074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  ParseScope LinkageScope(this, Scope::DeclScope);
160b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner  DeclPtrTy LinkageSpec
161074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    = Actions.ActOnStartLinkageSpecification(CurScope,
162074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                             /*FIXME: */SourceLocation(),
163074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                             Loc, LangBufPtr, StrSize,
164074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                       Tok.is(tok::l_brace)? Tok.getLocation()
165074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                           : SourceLocation());
166074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
167074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (Tok.isNot(tok::l_brace)) {
168074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    ParseDeclarationOrFunctionDefinition();
169074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec,
170074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                   SourceLocation());
171f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  }
172f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor
173f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  SourceLocation LBrace = ConsumeBrace();
174f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
175074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    ParseExternalDeclaration();
176f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  }
177c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
178f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
179074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, RBrace);
180c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner}
181e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
182f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
183f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'.
18497144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris LattnerParser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
18597144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                                     SourceLocation &DeclEnd) {
186f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_using) && "Not using token");
187f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
188f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'using'.
189f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation UsingLoc = ConsumeToken();
190f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
1912f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner  if (Tok.is(tok::kw_namespace))
192f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // Next token after 'using' is 'namespace' so it must be using-directive
19397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    return ParseUsingDirective(Context, UsingLoc, DeclEnd);
1942f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner
1952f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner  // Otherwise, it must be using-declaration.
19697144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  return ParseUsingDeclaration(Context, UsingLoc, DeclEnd);
197f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
198f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
199f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes
200f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed.
201f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
202f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       using-directive: [C++ 7.3.p4: namespace.udir]
203f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
204f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name ;
205f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive:
206f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
207f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name attributes[opt] ;
208f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
209b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris LattnerParser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
21097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                              SourceLocation UsingLoc,
21197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                              SourceLocation &DeclEnd) {
212f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
213f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
214f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'namespace'.
215f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation NamespcLoc = ConsumeToken();
216f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
217f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  CXXScopeSpec SS;
218f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse (optional) nested-name-specifier.
2197a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner  ParseOptionalCXXScopeSpecifier(SS);
220f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
221f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  AttributeList *AttrList = 0;
222f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  IdentifierInfo *NamespcName = 0;
223f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation IdentLoc = SourceLocation();
224f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
225f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse namespace-name.
226823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
227f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    Diag(Tok, diag::err_expected_namespace_name);
228f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // If there was invalid namespace name, skip to end of decl, and eat ';'.
229f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    SkipUntil(tok::semi);
230f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
231b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
232f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  }
233823c44e6d73141f642e207980b4021ddcf09897bChris Lattner
234823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse identifier.
235823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  NamespcName = Tok.getIdentifierInfo();
236823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  IdentLoc = ConsumeToken();
237823c44e6d73141f642e207980b4021ddcf09897bChris Lattner
238823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse (optional) attributes (most likely GNU strong-using extension).
239823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  if (Tok.is(tok::kw___attribute))
240823c44e6d73141f642e207980b4021ddcf09897bChris Lattner    AttrList = ParseAttributes();
241823c44e6d73141f642e207980b4021ddcf09897bChris Lattner
242823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Eat ';'.
24397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
2446869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi,
2456869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner                   AttrList ? diag::err_expected_semi_after_attribute_list :
2466869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner                   diag::err_expected_semi_after_namespace_name, "", tok::semi);
247f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
248f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  return Actions.ActOnUsingDirective(CurScope, UsingLoc, NamespcLoc, SS,
249823c44e6d73141f642e207980b4021ddcf09897bChris Lattner                                      IdentLoc, NamespcName, AttrList);
250f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
251f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
252f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that
253f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' was already seen.
254f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
255f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///     using-declaration: [C++ 7.3.p3: namespace.udecl]
256f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       'using' 'typename'[opt] ::[opt] nested-name-specifier
2579cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///               unqualified-id
2589cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///       'using' :: unqualified-id
259f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
260b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris LattnerParser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
26197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                                SourceLocation UsingLoc,
26297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                                SourceLocation &DeclEnd) {
2639cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  CXXScopeSpec SS;
2649cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  bool IsTypeName;
2659cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
2669cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Ignore optional 'typename'.
2679cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_typename)) {
2689cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    ConsumeToken();
2699cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = true;
2709cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
2719cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  else
2729cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = false;
2739cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
2749cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Parse nested-name-specifier.
2759cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS);
2769cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
2779cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  AttributeList *AttrList = 0;
2789cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
2799cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Check nested-name specifier.
2809cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (SS.isInvalid()) {
2819cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
2829cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return DeclPtrTy();
2839cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
2849cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::annot_template_id)) {
2859cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    Diag(Tok, diag::err_unexpected_template_spec_in_using);
2869cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
2879cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return DeclPtrTy();
2889cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
2890c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson
2900c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson  IdentifierInfo *TargetName = 0;
2910c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson  OverloadedOperatorKind Op = OO_None;
2920c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson  SourceLocation IdentLoc;
2930c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson
2940c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson  if (Tok.is(tok::kw_operator)) {
2950c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson    IdentLoc = Tok.getLocation();
2960c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson
2970c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson    Op = TryParseOperatorFunctionId();
2980c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson    if (!Op) {
2990c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson      // If there was an invalid operator, skip to end of decl, and eat ';'.
3000c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson      SkipUntil(tok::semi);
3010c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson      return DeclPtrTy();
3020c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson    }
3030c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson  } else if (Tok.is(tok::identifier)) {
3040c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson    // Parse identifier.
3050c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson    TargetName = Tok.getIdentifierInfo();
3060c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson    IdentLoc = ConsumeToken();
3070c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson  } else {
3080c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson    // FIXME: Use a better diagnostic here.
3099cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    Diag(Tok, diag::err_expected_ident_in_using);
3100c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson
3119cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    // If there was invalid identifier, skip to end of decl, and eat ';'.
3129cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
3139cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return DeclPtrTy();
3149cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
3159cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3169cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Parse (optional) attributes (most likely GNU strong-using extension).
3179cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw___attribute))
3189cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    AttrList = ParseAttributes();
3199cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3209cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Eat ';'.
3219cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  DeclEnd = Tok.getLocation();
3229cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
3239cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor                   AttrList ? "attributes list" : "namespace name", tok::semi);
3249cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3259cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  return Actions.ActOnUsingDeclaration(CurScope, UsingLoc, SS,
3260c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson                                       IdentLoc, TargetName, Op,
3270c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson                                       AttrList, IsTypeName);
328f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
329f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
330511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
331511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
332511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///      static_assert-declaration:
333511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///        static_assert ( constant-expression  ,  string-literal  ) ;
334511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
33597144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris LattnerParser::DeclPtrTy Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
336511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
337511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation StaticAssertLoc = ConsumeToken();
338511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
339511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (Tok.isNot(tok::l_paren)) {
340511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_lparen);
341b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
342511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
343511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
344511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation LParenLoc = ConsumeParen();
345e0762c92110dfdcdd207db461a4ea17afd168f1eDouglas Gregor
346511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  OwningExprResult AssertExpr(ParseConstantExpression());
347511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (AssertExpr.isInvalid()) {
348511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    SkipUntil(tok::semi);
349b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
350511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
351511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
352ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
353b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
354ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson
355511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (Tok.isNot(tok::string_literal)) {
356511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_string_literal);
357511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    SkipUntil(tok::semi);
358b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
359511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
360511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
361511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  OwningExprResult AssertMessage(ParseStringLiteralExpression());
362511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (AssertMessage.isInvalid())
363b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
364511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
36594b15fbc3a10cdfb1639528a8a773b66a1e7cd9eAnders Carlsson  MatchRHSPunctuation(tok::r_paren, LParenLoc);
366511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
36797144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
368511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert);
369511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
370ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson  return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, move(AssertExpr),
37194b15fbc3a10cdfb1639528a8a773b66a1e7cd9eAnders Carlsson                                              move(AssertMessage));
372511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson}
373511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
3746fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// ParseDecltypeSpecifier - Parse a C++0x decltype specifier.
3756fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
3766fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 'decltype' ( expression )
3776fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
3786fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlssonvoid Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
3796fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  assert(Tok.is(tok::kw_decltype) && "Not a decltype specifier");
3806fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
3816fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation StartLoc = ConsumeToken();
3826fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation LParenLoc = Tok.getLocation();
3836fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
3846fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
3856fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson                       "decltype")) {
3866fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    SkipUntil(tok::r_paren);
3876fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
3886fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  }
3896fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
3906fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Parse the expression
3916fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
3926fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // C++0x [dcl.type.simple]p4:
3936fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  //   The operand of the decltype specifier is an unevaluated operand.
3946fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  EnterExpressionEvaluationContext Unevaluated(Actions,
3956fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson                                               Action::Unevaluated);
3966fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  OwningExprResult Result = ParseExpression();
3976fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (Result.isInvalid()) {
3986fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    SkipUntil(tok::r_paren);
3996fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
4006fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  }
4016fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
4026fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Match the ')'
4036fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation RParenLoc;
4046fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (Tok.is(tok::r_paren))
4056fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    RParenLoc = ConsumeParen();
4066fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  else
4076fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    MatchRHSPunctuation(tok::r_paren, LParenLoc);
4086fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
4096fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (RParenLoc.isInvalid())
4106fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
4116fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
4126fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  const char *PrevSpec = 0;
4136fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Check for duplicate type specifiers (e.g. "int decltype(a)").
4146fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec,
4156fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson                         Result.release()))
4166fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
4176fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson}
4186fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
41942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// ParseClassName - Parse a C++ class-name, which names a class. Note
42042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// that we only check that the result names a type; semantic analysis
42142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// will need to verify that the type names a class. The result is
4227f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor/// either a type or NULL, depending on whether a type name was
42342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// found.
42442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///
42542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///       class-name: [C++ 9.1]
42642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///         identifier
4277f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor///         simple-template-id
42842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///
42931a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas GregorParser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
430d33c868d386ef47c2942e2dbff0d9955a8591fa9Fariborz Jahanian                                          const CXXScopeSpec *SS,
431d33c868d386ef47c2942e2dbff0d9955a8591fa9Fariborz Jahanian                                          bool DestrExpected) {
4327f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  // Check whether we have a template-id that names a type.
4337f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  if (Tok.is(tok::annot_template_id)) {
4347f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    TemplateIdAnnotation *TemplateId
4357f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
436c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor    if (TemplateId->Kind == TNK_Type_template) {
43731a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      AnnotateTemplateIdTokenAsType(SS);
4387f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
4397f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
4407f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      TypeTy *Type = Tok.getAnnotationValue();
4417f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      EndLocation = Tok.getAnnotationEndLoc();
4427f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      ConsumeToken();
44331a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor
44431a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      if (Type)
44531a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor        return Type;
44631a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      return true;
4477f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    }
4487f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
4497f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    // Fall through to produce an error below.
4507f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  }
4517f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
45242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  if (Tok.isNot(tok::identifier)) {
4531ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_class_name);
45431a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
45542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
45642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
45742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // We have an identifier; check whether it is actually a type.
458b696ea3a0693798daeafd896d77f0b8f1fec3cc5Douglas Gregor  TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(),
459b696ea3a0693798daeafd896d77f0b8f1fec3cc5Douglas Gregor                                     Tok.getLocation(), CurScope, SS);
46042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  if (!Type) {
461d33c868d386ef47c2942e2dbff0d9955a8591fa9Fariborz Jahanian    Diag(Tok, DestrExpected ? diag::err_destructor_class_name
462d33c868d386ef47c2942e2dbff0d9955a8591fa9Fariborz Jahanian                            : diag::err_expected_class_name);
46331a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
46442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
46542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
46642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Consume the identifier.
4677f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  EndLocation = ConsumeToken();
46842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  return Type;
46942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor}
47042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
471e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
472e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
473e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that
474e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// cannot start a definition.
475e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
476e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-specifier: [C++ class]
477e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}'
478e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}' attributes[opt]
479e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-head:
480e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key identifier[opt] base-clause[opt]
481e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier identifier base-clause[opt]
482e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier[opt] simple-template-id
483e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          base-clause[opt]
484e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   class-key attributes[opt] identifier[opt] base-clause[opt]
485e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   class-key attributes[opt] nested-name-specifier
486e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          identifier base-clause[opt]
487e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   class-key attributes[opt] nested-name-specifier[opt]
488e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          simple-template-id base-clause[opt]
489e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-key:
490e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'class'
491e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
492e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
493e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
494e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       elaborated-type-specifier: [C++ dcl.type.elab]
495e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key ::[opt] nested-name-specifier[opt] identifier
496e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
497e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          simple-template-id
498e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
499e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  Note that the C++ class-specifier and elaborated-type-specifier,
500e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  together, subsume the C99 struct-or-union-specifier:
501e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
502e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union-specifier: [C99 6.7.2.1]
503e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier[opt] '{' struct-contents '}'
504e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier
505e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier[opt] '{' struct-contents
506e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                                                         '}' attributes[opt]
507e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier
508e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union:
509e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
510e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
5114c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattnervoid Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
5124c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner                                 SourceLocation StartLoc, DeclSpec &DS,
5134d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                 const ParsedTemplateInfo &TemplateInfo,
51406c0fecd197fef21e265a41bca8dc5022de1f864Douglas Gregor                                 AccessSpecifier AS) {
5154c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  DeclSpec::TST TagType;
5164c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  if (TagTokKind == tok::kw_struct)
5174c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_struct;
5184c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  else if (TagTokKind == tok::kw_class)
5194c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_class;
5204c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  else {
5214c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    assert(TagTokKind == tok::kw_union && "Not a class specifier");
5224c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_union;
5234c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  }
524e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
525e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  AttributeList *Attr = 0;
526e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If attributes exist after tag, parse them.
527e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw___attribute))
528e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    Attr = ParseAttributes();
529e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
530f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff  // If declspecs exist after tag, parse them.
531290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman  if (Tok.is(tok::kw___declspec))
532290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman    Attr = ParseMicrosoftDeclSpec(Attr);
533f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff
534eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse the (optional) nested-name-specifier.
535eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  CXXScopeSpec SS;
53639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS))
53739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
538eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis      Diag(Tok, diag::err_expected_ident);
539cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
540cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  // Parse the (optional) class name or simple-template-id.
541e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  IdentifierInfo *Name = 0;
542e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation NameLoc;
54339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  TemplateIdAnnotation *TemplateId = 0;
544e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::identifier)) {
545e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    Name = Tok.getIdentifierInfo();
546e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    NameLoc = ConsumeToken();
54739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  } else if (Tok.is(tok::annot_template_id)) {
54839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
54939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    NameLoc = ConsumeToken();
550cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
551c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor    if (TemplateId->Kind != TNK_Type_template) {
55239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // The template-name in the simple-template-id refers to
55339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // something other than a class template. Give an appropriate
55439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // error message and skip to the ';'.
55539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SourceRange Range(NameLoc);
55639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      if (SS.isNotEmpty())
55739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        Range.setBegin(SS.getBeginLoc());
55839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
55939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
56039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        << Name << static_cast<int>(TemplateId->Kind) << Range;
561cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
56239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      DS.SetTypeSpecError();
56339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SkipUntil(tok::semi, false, true);
56439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      TemplateId->Destroy();
56539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      return;
566cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    }
567e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
568e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
569e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // There are three options here.  If we have 'struct foo;', then
570e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // this is a forward declaration.  If we have 'struct foo {...' or
57139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  // 'struct foo :...' then this is a definition. Otherwise we have
572e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // something like 'struct foo xyz', a reference.
573e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  Action::TagKind TK;
574e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon)))
575e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    TK = Action::TK_Definition;
5765dc2af12bdb8c71c01556f7d5780c5ef94af0306Anders Carlsson  else if (Tok.is(tok::semi) && !DS.isFriendSpecified())
577e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    TK = Action::TK_Declaration;
578e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  else
579e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    TK = Action::TK_Reference;
580e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
58139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  if (!Name && !TemplateId && TK != Action::TK_Definition) {
582e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // We have a declaration or reference to an anonymous class.
5831ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(StartLoc, diag::err_anon_type_definition)
5841ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner      << DeclSpec::getSpecifierName(TagType);
585e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
586e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Skip the rest of this declarator, up until the comma or semicolon.
587e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SkipUntil(tok::comma, true);
58839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
58939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    if (TemplateId)
59039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      TemplateId->Destroy();
591e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    return;
592e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
593e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
594ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  // Create the tag portion of the class or class template.
595212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor  Action::DeclResult TagOrTempResult;
5964d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor  TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
5974d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
5984d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor  // FIXME: When TK == TK_Reference and we have a template-id, we need
5994d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor  // to turn that template-id into a type.
6004d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
601402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor  bool Owned = false;
60239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  if (TemplateId && TK != Action::TK_Reference) {
6034d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // Explicit specialization, class template partial specialization,
6044d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // or explicit instantiation.
60539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    ASTTemplateArgsPtr TemplateArgsPtr(Actions,
60639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->getTemplateArgs(),
60739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->getTemplateArgIsType(),
60839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->NumArgs);
6094d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
6104d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        TK == Action::TK_Declaration) {
6114d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit instantiation of a class template.
6124d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
6134d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        = Actions.ActOnExplicitInstantiation(CurScope,
6144d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateInfo.TemplateLoc,
6154d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TagType,
6164d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             StartLoc,
6174d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             SS,
6184d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                     TemplateTy::make(TemplateId->Template),
6194d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateId->TemplateNameLoc,
6204d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateId->LAngleLoc,
6214d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateArgsPtr,
6224d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                      TemplateId->getTemplateArgLocations(),
6234d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateId->RAngleLoc,
6244d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             Attr);
6254d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    } else {
6264d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit specialization or a class template
6274d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // partial specialization.
6284d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TemplateParameterLists FakedParamLists;
6294d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
6304d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
6314d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // This looks like an explicit instantiation, because we have
6324d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // something like
6334d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
6344d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //   template class Foo<X>
6354d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
6363f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor        // but it actually has a definition. Most likely, this was
6374d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // meant to be an explicit specialization, but the user forgot
6384d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // the '<>' after 'template'.
6393f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor        assert(TK == Action::TK_Definition && "Expected a definition here");
6404d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
6414d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        SourceLocation LAngleLoc
6424d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
6434d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        Diag(TemplateId->TemplateNameLoc,
6444d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor             diag::err_explicit_instantiation_with_definition)
6454d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          << SourceRange(TemplateInfo.TemplateLoc)
6464d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          << CodeModificationHint::CreateInsertion(LAngleLoc, "<>");
6474d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
6484d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // Create a fake template parameter list that contains only
6494d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // "template<>", so that we treat this construct as a class
6504d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // template specialization.
6514d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        FakedParamLists.push_back(
6524d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          Actions.ActOnTemplateParameterList(0, SourceLocation(),
6534d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateInfo.TemplateLoc,
6544d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             LAngleLoc,
6554d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             0, 0,
6564d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             LAngleLoc));
6574d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        TemplateParams = &FakedParamLists;
6584d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      }
6594d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
6604d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // Build the class template specialization.
6614d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
6624d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TK,
66339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       StartLoc, SS,
6647532dc66648cfe7432c9fe66dec5225f0ab301c6Douglas Gregor                       TemplateTy::make(TemplateId->Template),
66539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       TemplateId->TemplateNameLoc,
66639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       TemplateId->LAngleLoc,
66739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       TemplateArgsPtr,
66839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       TemplateId->getTemplateArgLocations(),
66939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       TemplateId->RAngleLoc,
67039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       Attr,
671cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                       Action::MultiTemplateParamsArg(Actions,
672cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                    TemplateParams? &(*TemplateParams)[0] : 0,
673cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                 TemplateParams? TemplateParams->size() : 0));
6744d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    }
67539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    TemplateId->Destroy();
6763f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else if (TemplateParams && TK != Action::TK_Reference) {
6773f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Class template declaration or definition.
678212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor    TagOrTempResult = Actions.ActOnClassTemplate(CurScope, TagType, TK,
679212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor                                                 StartLoc, SS, Name, NameLoc,
680212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor                                                 Attr,
681ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                       Action::MultiTemplateParamsArg(Actions,
682ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor                                                      &(*TemplateParams)[0],
6835aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson                                                      TemplateParams->size()),
6845aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson                                                 AS);
6853f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
6863f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor             TK == Action::TK_Declaration) {
6873f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Explicit instantiation of a member of a class template
6883f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // specialization, e.g.,
6893f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
6903f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //   template struct Outer<int>::Inner;
6913f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
6923f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    TagOrTempResult
6933f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor      = Actions.ActOnExplicitInstantiation(CurScope,
6943f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor                                           TemplateInfo.TemplateLoc,
6953f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor                                           TagType, StartLoc, SS, Name,
6963f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor                                           NameLoc, Attr);
6973f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else {
6983f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
6993f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor        TK == Action::TK_Definition) {
7003f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor      // FIXME: Diagnose this particular error.
7013f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    }
7023f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor
7033f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Declaration or definition of a class type
7043f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    TagOrTempResult = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS,
705402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor                                       Name, NameLoc, Attr, AS, Owned);
7063f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  }
707e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
708e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the optional base clause (C++ only).
70922bd905673a73ccb9b5e45a7038ec060c9650ffeChris Lattner  if (getLang().CPlusPlus && Tok.is(tok::colon))
710212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor    ParseBaseClause(TagOrTempResult.get());
711e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
712e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If there is a body, parse it and inform the actions module.
713e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::l_brace))
71407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    if (getLang().CPlusPlus)
715212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
71607952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    else
717212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
718e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  else if (TK == Action::TK_Definition) {
719e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // FIXME: Complain that we have a base-specifier list but no
720e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // definition.
7211ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lbrace);
722e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
723e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
724e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  const char *PrevSpec = 0;
72566e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson  if (TagOrTempResult.isInvalid()) {
726ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    DS.SetTypeSpecError();
72766e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson    return;
72866e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson  }
72966e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson
73066e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson  if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec,
731402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor                         TagOrTempResult.get().getAs<void>(), Owned))
7321ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
733d4f551b3491777ffcc7f2664327810219b7e0e16Anders Carlsson
734d4f551b3491777ffcc7f2664327810219b7e0e16Anders Carlsson  if (DS.isFriendSpecified())
735d4f551b3491777ffcc7f2664327810219b7e0e16Anders Carlsson    Actions.ActOnFriendDecl(CurScope, DS.getFriendSpecLoc(),
736d4f551b3491777ffcc7f2664327810219b7e0e16Anders Carlsson                            TagOrTempResult.get());
737e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
738e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
739e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
740e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
741e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-clause : [C++ class.derived]
742e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ':' base-specifier-list
743e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier-list:
744e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier '...'[opt]
745e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier-list ',' base-specifier '...'[opt]
746b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattnervoid Parser::ParseBaseClause(DeclPtrTy ClassDecl) {
747e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  assert(Tok.is(tok::colon) && "Not a base clause");
748e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  ConsumeToken();
749e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
750f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Build up an array of parsed base specifiers.
751f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  llvm::SmallVector<BaseTy *, 8> BaseInfo;
752f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
753e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  while (true) {
754e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Parse a base-specifier.
755f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    BaseResult Result = ParseBaseSpecifier(ClassDecl);
7565ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor    if (Result.isInvalid()) {
757e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Skip the rest of this base specifier, up until the comma or
758e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // opening brace.
759f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      SkipUntil(tok::comma, tok::l_brace, true, true);
760f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    } else {
761f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      // Add this to our array of base specifiers.
7625ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor      BaseInfo.push_back(Result.get());
763e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
764e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
765e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // If the next token is a comma, consume it and keep reading
766e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // base-specifiers.
767e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (Tok.isNot(tok::comma)) break;
768e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
769e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Consume the comma.
770e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
771e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
772f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
773f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Attach the base specifiers
774beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad  Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size());
775e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
776e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
777e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
778e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example:
779e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///    class foo : public bar, virtual private baz {
780e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers.
781e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
782e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier: [C++ class.derived]
783e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ::[opt] nested-name-specifier[opt] class-name
784e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt]
785e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                        class-name
786e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
787e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                        class-name
788b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris LattnerParser::BaseResult Parser::ParseBaseSpecifier(DeclPtrTy ClassDecl) {
789e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  bool IsVirtual = false;
790e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation StartLoc = Tok.getLocation();
791e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
792e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword.
793e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
794e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
795e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
796e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
797e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
798e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse an (optional) access specifier.
799e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  AccessSpecifier Access = getAccessSpecifierIfPresent();
800e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Access)
801e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
802e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
803e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword (again!), in case it came after the
804e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // access specifier.
805e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
806e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SourceLocation VirtualLoc = ConsumeToken();
807e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (IsVirtual) {
808e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Complain about duplicate 'virtual'
8091ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner      Diag(VirtualLoc, diag::err_dup_virtual)
81031a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor        << CodeModificationHint::CreateRemoval(SourceRange(VirtualLoc));
811e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
812e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
813e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
814e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
815e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
816eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse optional '::' and optional nested-name-specifier.
817eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  CXXScopeSpec SS;
8187a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner  ParseOptionalCXXScopeSpecifier(SS);
819e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
820e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // The location of the base class itself.
821e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation BaseLoc = Tok.getLocation();
82242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
82342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Parse the class-name.
8247f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceLocation EndLocation;
82531a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor  TypeResult BaseType = ParseClassName(EndLocation, &SS);
82631a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor  if (BaseType.isInvalid())
82742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor    return true;
828e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
829e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Find the complete source range for the base-specifier.
8307f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceRange Range(StartLoc, EndLocation);
831e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
832e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Notify semantic analysis that we have parsed a complete
833e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // base-specifier.
834a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl  return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
83531a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor                                    BaseType.get(), BaseLoc);
836e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
837e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
838e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is
839e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier.
840e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
841e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       access-specifier: [C++ class.derived]
842e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'private'
843e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'protected'
844e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'public'
8451b7f89846f10681ce3cbe89ef5d60691d55bd918Douglas GregorAccessSpecifier Parser::getAccessSpecifierIfPresent() const
846e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor{
847e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  switch (Tok.getKind()) {
848e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  default: return AS_none;
849e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_private: return AS_private;
850e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_protected: return AS_protected;
851e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_public: return AS_public;
852e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
853e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
8544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
855d33133cdc1af466f9c276249b2621be03867888bEli Friedmanvoid Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
856d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                             DeclPtrTy ThisDecl) {
857d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // We just declared a member function. If this member function
858d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // has any default arguments, we'll need to parse them later.
859d33133cdc1af466f9c276249b2621be03867888bEli Friedman  LateParsedMethodDeclaration *LateMethod = 0;
860d33133cdc1af466f9c276249b2621be03867888bEli Friedman  DeclaratorChunk::FunctionTypeInfo &FTI
861d33133cdc1af466f9c276249b2621be03867888bEli Friedman    = DeclaratorInfo.getTypeObject(0).Fun;
862d33133cdc1af466f9c276249b2621be03867888bEli Friedman  for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
863d33133cdc1af466f9c276249b2621be03867888bEli Friedman    if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
864d33133cdc1af466f9c276249b2621be03867888bEli Friedman      if (!LateMethod) {
865d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Push this method onto the stack of late-parsed method
866d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // declarations.
867d33133cdc1af466f9c276249b2621be03867888bEli Friedman        getCurrentClass().MethodDecls.push_back(
868d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                LateParsedMethodDeclaration(ThisDecl));
869d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateMethod = &getCurrentClass().MethodDecls.back();
870d33133cdc1af466f9c276249b2621be03867888bEli Friedman
871d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Add all of the parameters prior to this one (they don't
872d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // have default arguments).
873d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateMethod->DefaultArgs.reserve(FTI.NumArgs);
874d33133cdc1af466f9c276249b2621be03867888bEli Friedman        for (unsigned I = 0; I < ParamIdx; ++I)
875d33133cdc1af466f9c276249b2621be03867888bEli Friedman          LateMethod->DefaultArgs.push_back(
876d33133cdc1af466f9c276249b2621be03867888bEli Friedman                    LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param));
877d33133cdc1af466f9c276249b2621be03867888bEli Friedman      }
878d33133cdc1af466f9c276249b2621be03867888bEli Friedman
879d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // Add this parameter to the list of parameters (it or may
880d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // not have a default argument).
881d33133cdc1af466f9c276249b2621be03867888bEli Friedman      LateMethod->DefaultArgs.push_back(
882d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
883d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                  FTI.ArgInfo[ParamIdx].DefaultArgTokens));
884d33133cdc1af466f9c276249b2621be03867888bEli Friedman    }
885d33133cdc1af466f9c276249b2621be03867888bEli Friedman  }
886d33133cdc1af466f9c276249b2621be03867888bEli Friedman}
887d33133cdc1af466f9c276249b2621be03867888bEli Friedman
8884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
8894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
8904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declaration:
8914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         decl-specifier-seq[opt] member-declarator-list[opt] ';'
8924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         function-definition ';'[opt]
8934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
8944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         using-declaration                                            [TODO]
895511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration
8965aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson///         template-declaration
897bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU]   '__extension__' member-declaration
8984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
8994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator-list:
9004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator
9014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator-list ',' member-declarator
9024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
9034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator:
9044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         declarator pure-specifier[opt]
9054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         declarator constant-initializer[opt]
9064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         identifier[opt] ':' constant-expression
9074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
908e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl///       pure-specifier:
9094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '= 0'
9104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
9114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       constant-initializer:
9124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '=' constant-expression
9134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
914682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattnervoid Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
915511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  // static_assert-declaration
916682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  if (Tok.is(tok::kw_static_assert)) {
91797144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
91897144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    ParseStaticAssertDeclaration(DeclEnd);
919682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
920682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
921511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
922682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  if (Tok.is(tok::kw_template)) {
92397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
9244d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd,
9254d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                         AS);
926682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
927682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
9285aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson
929bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  // Handle:  member-declaration ::= '__extension__' member-declaration
930bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  if (Tok.is(tok::kw___extension__)) {
931bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    // __extension__ silences extension warnings in the subexpression.
932bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
933bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ConsumeToken();
934bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    return ParseCXXClassMemberDeclaration(AS);
935bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  }
9369cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
9379cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_using)) {
9389cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    // Eat 'using'.
9399cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SourceLocation UsingLoc = ConsumeToken();
9409cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
9419cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    if (Tok.is(tok::kw_namespace)) {
9429cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      Diag(UsingLoc, diag::err_using_namespace_in_class);
9439cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SkipUntil(tok::semi, true, true);
9449cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    }
9459cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    else {
9469cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SourceLocation DeclEnd;
9479cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      // Otherwise, it must be using-declaration.
9489cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      ParseUsingDeclaration(Declarator::MemberContext, UsingLoc, DeclEnd);
9499cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    }
9509cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return;
9519cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
9529cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
9534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  SourceLocation DSStart = Tok.getLocation();
9544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // decl-specifier-seq:
9554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Parse the common declaration-specifiers piece.
9564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  DeclSpec DS;
9574d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor  ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS);
9584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
9594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::semi)) {
9604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
9614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // C++ 9.2p7: The member-declarator-list can be omitted only after a
9624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // class-specifier or an enum-specifier or in a friend declaration.
9634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // FIXME: Friend declarations.
9644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    switch (DS.getTypeSpecType()) {
965682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    case DeclSpec::TST_struct:
966682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    case DeclSpec::TST_union:
967682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    case DeclSpec::TST_class:
968682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    case DeclSpec::TST_enum:
969682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
970682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
971682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    default:
972682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      Diag(DSStart, diag::err_no_declarators);
973682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
9744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
9754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
97607952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
9774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  Declarator DeclaratorInfo(DS, Declarator::MemberContext);
9784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
9793a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis  if (Tok.isNot(tok::colon)) {
9803a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Parse the first declarator.
9813a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    ParseDeclarator(DeclaratorInfo);
9823a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Error parsing the declarator?
98310bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor    if (!DeclaratorInfo.hasName()) {
9843a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      // If so, skip until the semi-colon or a }.
9854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      SkipUntil(tok::r_brace, true);
9863a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (Tok.is(tok::semi))
9873a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeToken();
988682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
9894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
9904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
9913a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // function-definition:
9927ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    if (Tok.is(tok::l_brace)
993d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl        || (DeclaratorInfo.isFunctionDeclarator() &&
994d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl            (Tok.is(tok::colon) || Tok.is(tok::kw_try)))) {
9953a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (!DeclaratorInfo.isFunctionDeclarator()) {
9963a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        Diag(Tok, diag::err_func_def_no_params);
9973a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
9983a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        SkipUntil(tok::r_brace, true);
999682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
10003a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
10013a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis
10023a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
10033a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        Diag(Tok, diag::err_function_declared_typedef);
10043a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // This recovery skips the entire function body. It would be nice
10053a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // to simply call ParseCXXInlineMethodDef() below, however Sema
10063a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // assumes the declarator represents a function, not a typedef.
10073a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
10083a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        SkipUntil(tok::r_brace, true);
1009682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
10103a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
10114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1012682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      ParseCXXInlineMethodDef(AS, DeclaratorInfo);
1013682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
10143a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    }
10154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
10164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
10174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // member-declarator-list:
10184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator
10194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator-list ',' member-declarator
10204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1021682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup;
102215faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl  OwningExprResult BitfieldSize(Actions);
102315faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl  OwningExprResult Init(Actions);
1024e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl  bool Deleted = false;
10254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
10264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  while (1) {
10274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
10284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // member-declarator:
10294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   declarator pure-specifier[opt]
10304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   declarator constant-initializer[opt]
10314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   identifier[opt] ':' constant-expression
10324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
10334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::colon)) {
10344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
10350e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      BitfieldSize = ParseConstantExpression();
10360e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      if (BitfieldSize.isInvalid())
10374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        SkipUntil(tok::comma, true, true);
10384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
10394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
10404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // pure-specifier:
10414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   '= 0'
10424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //
10434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // constant-initializer:
10444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   '=' constant-expression
1045e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //
1046e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    // defaulted/deleted function-definition:
1047e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //   '=' 'default'                          [TODO]
1048e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //   '=' 'delete'
10494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
10504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::equal)) {
10514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
1052e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl      if (getLang().CPlusPlus0x && Tok.is(tok::kw_delete)) {
1053e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        ConsumeToken();
1054e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        Deleted = true;
1055e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl      } else {
1056e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        Init = ParseInitializer();
1057e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        if (Init.isInvalid())
1058e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl          SkipUntil(tok::comma, true, true);
1059e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl      }
10604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
10614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
10624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If attributes exist after the declarator, parse them.
1063ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    if (Tok.is(tok::kw___attribute)) {
1064ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      SourceLocation Loc;
1065ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      AttributeList *AttrList = ParseAttributes(&Loc);
1066ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      DeclaratorInfo.AddAttributes(AttrList, Loc);
1067ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    }
10684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
106907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // NOTE: If Sema is the Action module and declarator is an instance field,
1070682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    // this call will *not* return the created decl; It will return null.
107107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // See Sema::ActOnCXXMemberDeclarator for details.
1072682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    DeclPtrTy ThisDecl = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
1073682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner                                                          DeclaratorInfo,
1074682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner                                                          BitfieldSize.release(),
1075e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl                                                          Init.release(),
1076e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl                                                          Deleted);
1077682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    if (ThisDecl)
1078682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      DeclsInGroup.push_back(ThisDecl);
10794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
108072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    if (DeclaratorInfo.isFunctionDeclarator() &&
108172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor        DeclaratorInfo.getDeclSpec().getStorageClassSpec()
108272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor          != DeclSpec::SCS_typedef) {
1083d33133cdc1af466f9c276249b2621be03867888bEli Friedman      HandleMemberFunctionDefaultArgs(DeclaratorInfo, ThisDecl);
108472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    }
108572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor
10864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If we don't have a comma, it is either the end of the list (a ';')
10874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // or an error, bail out.
10884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.isNot(tok::comma))
10894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
10904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
10914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Consume the comma.
10924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
10934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
10944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Parse the next declarator.
10954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    DeclaratorInfo.clear();
109615faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl    BitfieldSize = 0;
109715faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl    Init = 0;
1098e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    Deleted = false;
10994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Attributes are only allowed on the second declarator.
1101ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    if (Tok.is(tok::kw___attribute)) {
1102ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      SourceLocation Loc;
1103ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      AttributeList *AttrList = ParseAttributes(&Loc);
1104ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      DeclaratorInfo.AddAttributes(AttrList, Loc);
1105ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    }
11064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11073a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    if (Tok.isNot(tok::colon))
11083a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      ParseDeclarator(DeclaratorInfo);
11094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
11104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::semi)) {
11124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
1113c1dc653b08226c1d8e1732f9d8b03b82869900bcEli Friedman    Actions.FinalizeDeclaratorGroup(CurScope, DS, DeclsInGroup.data(),
1114682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner                                    DeclsInGroup.size());
1115682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
11164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
11174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  Diag(Tok, diag::err_expected_semi_decl_list);
11194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Skip to end of block or statement
11204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  SkipUntil(tok::r_brace, true, true);
11214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::semi))
11224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
1123682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  return;
11244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
11254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition.
11274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
11284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-specification:
11294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declaration member-specification[opt]
11304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         access-specifier ':' member-specification[opt]
11314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
11324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidisvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
1133b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner                                         unsigned TagType, DeclPtrTy TagDecl) {
113431fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta  assert((TagType == DeclSpec::TST_struct ||
11354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis         TagType == DeclSpec::TST_union  ||
113631fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta         TagType == DeclSpec::TST_class) && "Invalid TagType!");
11374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
113849f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner  PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
113949f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner                                        PP.getSourceManager(),
114049f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner                                        "parsing struct/union/class body");
114127b7f1028255149978356f85c4825522d234a253Chris Lattner
11424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  SourceLocation LBraceLoc = ConsumeBrace();
11434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11446569d68745c8213709740337d2be52b031384f58Douglas Gregor  // Determine whether this is a top-level (non-nested) class.
11456569d68745c8213709740337d2be52b031384f58Douglas Gregor  bool TopLevelClass = ClassStack.empty() ||
11466569d68745c8213709740337d2be52b031384f58Douglas Gregor    CurScope->isInCXXInlineMethodScope();
11474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Enter a scope for the class.
11493218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
11504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11516569d68745c8213709740337d2be52b031384f58Douglas Gregor  // Note that we are parsing a new (potentially-nested) class definition.
11526569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingClassDefinition ParsingDef(*this, TagDecl, TopLevelClass);
11536569d68745c8213709740337d2be52b031384f58Douglas Gregor
1154ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  if (TagDecl)
1155ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    Actions.ActOnTagStartDefinition(CurScope, TagDecl);
1156ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  else {
1157ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    SkipUntil(tok::r_brace, false, false);
1158ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    return;
1159ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  }
11604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // C++ 11p3: Members of a class defined with the keyword class are private
11624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // by default. Members of a class defined with the keywords struct or union
11634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // are public by default.
11644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  AccessSpecifier CurAS;
11654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (TagType == DeclSpec::TST_class)
11664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_private;
11674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  else
11684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_public;
11694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // While we still have something to read, read the member-declarations.
11714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
11724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Each iteration of this loop reads one member-declaration.
11734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Check for extraneous top-level semicolon.
11754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::semi)) {
11764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Diag(Tok, diag::ext_extra_struct_semi);
11774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
11784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      continue;
11794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
11804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    AccessSpecifier AS = getAccessSpecifierIfPresent();
11824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (AS != AS_none) {
11834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      // Current token is a C++ access specifier.
11844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      CurAS = AS;
11854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
11864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ExpectAndConsume(tok::colon, diag::err_expected_colon);
11874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      continue;
11884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
11894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Parse all the comma separated declarators.
11914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ParseCXXClassMemberDeclaration(CurAS);
11924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
11934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
11954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  AttributeList *AttrList = 0;
11974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // If attributes exist after class contents, parse them.
11984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::kw___attribute))
11994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    AttrList = ParseAttributes(); // FIXME: where should I put them?
12004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
12014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl,
12024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis                                            LBraceLoc, RBraceLoc);
12034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
12044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // C++ 9.2p2: Within the class member-specification, the class is regarded as
12054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // complete within function bodies, default arguments,
12064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // exception-specifications, and constructor ctor-initializers (including
12074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // such things in nested classes).
12084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //
120972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor  // FIXME: Only function bodies and constructor ctor-initializers are
121072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor  // parsed correctly, fix the rest.
12116569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (TopLevelClass) {
12124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // We are not inside a nested class. This class and its nested classes
121372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    // are complete and we can parse the delayed portions of method
121472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    // declarations and the lexed inline method definitions.
12156569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDeclarations(getCurrentClass());
12166569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDefs(getCurrentClass());
12174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
12184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
12194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Leave the class scope.
12206569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingDef.Pop();
12218935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ClassScope.Exit();
12224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
122307a5b282fbe719986df9ed05543081ea0ed94aa5Argyrios Kyrtzidis  Actions.ActOnTagFinishDefinition(CurScope, TagDecl, RBraceLoc);
12244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
12257ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
12267ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer,
12277ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a
12287ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers
12297ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below:
12307ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
12317ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code
12327ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { };
12337ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base {
12347ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   int x;
12357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   float f;
12367ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public:
12377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   Derived(float f) : Base(), x(17), f(f) { }
12387ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// };
12397ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode
12407ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
12417ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++]  ctor-initializer:
12427ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///          ':' mem-initializer-list
12437ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
12447ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++]  mem-initializer-list:
12457ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///          mem-initializer
12467ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///          mem-initializer , mem-initializer-list
1247b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattnervoid Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) {
12487ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
12497ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
12507ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation ColonLoc = ConsumeToken();
12517ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
12527ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  llvm::SmallVector<MemInitTy*, 4> MemInitializers;
12537ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
12547ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  do {
12557ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
12565ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor    if (!MemInit.isInvalid())
12575ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor      MemInitializers.push_back(MemInit.get());
12587ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
12597ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    if (Tok.is(tok::comma))
12607ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      ConsumeToken();
12617ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    else if (Tok.is(tok::l_brace))
12627ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
12637ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    else {
12647ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      // Skip over garbage, until we get to '{'.  Don't eat the '{'.
1265d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl      Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
12667ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      SkipUntil(tok::l_brace, true, true);
12677ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
12687ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    }
12697ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  } while (true);
12707ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
12717ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc,
1272beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad                               MemInitializers.data(), MemInitializers.size());
12737ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
12747ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
12757ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is
12767ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one
12777ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See
12787ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example.
12797ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
12807ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer:
12817ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         mem-initializer-id '(' expression-list[opt] ')'
12827ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
12837ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id:
12847ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         '::'[opt] nested-name-specifier[opt] class-name
12857ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         identifier
1286b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris LattnerParser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
1287bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  // parse '::'[opt] nested-name-specifier[opt]
1288bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  CXXScopeSpec SS;
1289bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  ParseOptionalCXXScopeSpecifier(SS);
1290961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  TypeTy *TemplateTypeTy = 0;
1291961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (Tok.is(tok::annot_template_id)) {
1292961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    TemplateIdAnnotation *TemplateId
1293961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
1294961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    if (TemplateId->Kind == TNK_Type_template) {
1295961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      AnnotateTemplateIdTokenAsType(&SS);
1296961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
1297961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      TemplateTypeTy = Tok.getAnnotationValue();
1298961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    }
1299961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    // FIXME. May need to check for TNK_Dependent_template as well.
1300961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  }
1301961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (!TemplateTypeTy && Tok.isNot(tok::identifier)) {
13021ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_member_or_base_name);
13037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
13047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
1305961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian
13067ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Get the identifier. This may be a member name or a class name,
13077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // but we'll let the semantic analysis determine which it is.
1308961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  IdentifierInfo *II = Tok.is(tok::identifier) ? Tok.getIdentifierInfo() : 0;
13097ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation IdLoc = ConsumeToken();
13107ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
13117ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Parse the '('.
13127ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  if (Tok.isNot(tok::l_paren)) {
13131ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen);
13147ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
13157ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
13167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation LParenLoc = ConsumeParen();
13177ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
13187ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Parse the optional expression-list.
1319a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl  ExprVector ArgExprs(Actions);
13207ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  CommaLocsTy CommaLocs;
13217ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
13227ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    SkipUntil(tok::r_paren);
13237ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
13247ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
13257ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
13267ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
13277ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
1328961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, SS, II,
1329961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian                                     TemplateTypeTy, IdLoc,
1330a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl                                     LParenLoc, ArgExprs.take(),
1331beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad                                     ArgExprs.size(), CommaLocs.data(),
1332beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad                                     RParenLoc);
13337ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
13340fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
13350fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// ParseExceptionSpecification - Parse a C++ exception-specification
13360fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// (C++ [except.spec]).
13370fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
1338a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       exception-specification:
1339a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         'throw' '(' type-id-list [opt] ')'
1340a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS]    'throw' '(' '...' ')'
13410fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
1342a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       type-id-list:
1343a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         type-id
1344a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         type-id-list ',' type-id
13450fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
13467dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redlbool Parser::ParseExceptionSpecification(SourceLocation &EndLoc,
1347ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl                                         llvm::SmallVector<TypeTy*, 2>
1348ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl                                             &Exceptions,
1349ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl                                         llvm::SmallVector<SourceRange, 2>
1350ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl                                             &Ranges,
13517dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl                                         bool &hasAnyExceptionSpec) {
13520fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  assert(Tok.is(tok::kw_throw) && "expected throw");
13530fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
13540fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  SourceLocation ThrowLoc = ConsumeToken();
13550fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
13560fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  if (!Tok.is(tok::l_paren)) {
13570fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor    return Diag(Tok, diag::err_expected_lparen_after) << "throw";
13580fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
13590fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  SourceLocation LParenLoc = ConsumeParen();
13600fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
1361a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // Parse throw(...), a Microsoft extension that means "this function
1362a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // can throw anything".
1363a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  if (Tok.is(tok::ellipsis)) {
13647dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl    hasAnyExceptionSpec = true;
1365a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    SourceLocation EllipsisLoc = ConsumeToken();
1366a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    if (!getLang().Microsoft)
1367a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor      Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
1368ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1369a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    return false;
1370a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  }
1371a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor
13720fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  // Parse the sequence of type-ids.
1373ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl  SourceRange Range;
13740fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  while (Tok.isNot(tok::r_paren)) {
1375ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    TypeResult Res(ParseTypeName(&Range));
1376ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    if (!Res.isInvalid()) {
13777dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl      Exceptions.push_back(Res.get());
1378ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl      Ranges.push_back(Range);
1379ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    }
13800fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor    if (Tok.is(tok::comma))
13810fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      ConsumeToken();
13827dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl    else
13830fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      break;
13840fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
13850fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
1386ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl  EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
13870fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  return false;
13880fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor}
13896569d68745c8213709740337d2be52b031384f58Douglas Gregor
13906569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief We have just started parsing the definition of a new class,
13916569d68745c8213709740337d2be52b031384f58Douglas Gregor/// so push that class onto our stack of classes that is currently
13926569d68745c8213709740337d2be52b031384f58Douglas Gregor/// being parsed.
13936569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::PushParsingClass(DeclPtrTy ClassDecl, bool TopLevelClass) {
13946569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert((TopLevelClass || !ClassStack.empty()) &&
13956569d68745c8213709740337d2be52b031384f58Douglas Gregor         "Nested class without outer class");
13966569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.push(new ParsingClass(ClassDecl, TopLevelClass));
13976569d68745c8213709740337d2be52b031384f58Douglas Gregor}
13986569d68745c8213709740337d2be52b031384f58Douglas Gregor
13996569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Deallocate the given parsed class and all of its nested
14006569d68745c8213709740337d2be52b031384f58Douglas Gregor/// classes.
14016569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
14026569d68745c8213709740337d2be52b031384f58Douglas Gregor  for (unsigned I = 0, N = Class->NestedClasses.size(); I != N; ++I)
14036569d68745c8213709740337d2be52b031384f58Douglas Gregor    DeallocateParsedClasses(Class->NestedClasses[I]);
14046569d68745c8213709740337d2be52b031384f58Douglas Gregor  delete Class;
14056569d68745c8213709740337d2be52b031384f58Douglas Gregor}
14066569d68745c8213709740337d2be52b031384f58Douglas Gregor
14076569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Pop the top class of the stack of classes that are
14086569d68745c8213709740337d2be52b031384f58Douglas Gregor/// currently being parsed.
14096569d68745c8213709740337d2be52b031384f58Douglas Gregor///
14106569d68745c8213709740337d2be52b031384f58Douglas Gregor/// This routine should be called when we have finished parsing the
14116569d68745c8213709740337d2be52b031384f58Douglas Gregor/// definition of a class, but have not yet popped the Scope
14126569d68745c8213709740337d2be52b031384f58Douglas Gregor/// associated with the class's definition.
14136569d68745c8213709740337d2be52b031384f58Douglas Gregor///
14146569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \returns true if the class we've popped is a top-level class,
14156569d68745c8213709740337d2be52b031384f58Douglas Gregor/// false otherwise.
14166569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::PopParsingClass() {
14176569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");
14186569d68745c8213709740337d2be52b031384f58Douglas Gregor
14196569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingClass *Victim = ClassStack.top();
14206569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.pop();
14216569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (Victim->TopLevelClass) {
14226569d68745c8213709740337d2be52b031384f58Douglas Gregor    // Deallocate all of the nested classes of this class,
14236569d68745c8213709740337d2be52b031384f58Douglas Gregor    // recursively: we don't need to keep any of this information.
14246569d68745c8213709740337d2be52b031384f58Douglas Gregor    DeallocateParsedClasses(Victim);
14256569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
14266569d68745c8213709740337d2be52b031384f58Douglas Gregor  }
14276569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Missing top-level class?");
14286569d68745c8213709740337d2be52b031384f58Douglas Gregor
14296569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (Victim->MethodDecls.empty() && Victim->MethodDefs.empty() &&
14306569d68745c8213709740337d2be52b031384f58Douglas Gregor      Victim->NestedClasses.empty()) {
14316569d68745c8213709740337d2be52b031384f58Douglas Gregor    // The victim is a nested class, but we will not need to perform
14326569d68745c8213709740337d2be52b031384f58Douglas Gregor    // any processing after the definition of this class since it has
14336569d68745c8213709740337d2be52b031384f58Douglas Gregor    // no members whose handling was delayed. Therefore, we can just
14346569d68745c8213709740337d2be52b031384f58Douglas Gregor    // remove this nested class.
14356569d68745c8213709740337d2be52b031384f58Douglas Gregor    delete Victim;
14366569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
14376569d68745c8213709740337d2be52b031384f58Douglas Gregor  }
14386569d68745c8213709740337d2be52b031384f58Douglas Gregor
14396569d68745c8213709740337d2be52b031384f58Douglas Gregor  // This nested class has some members that will need to be processed
14406569d68745c8213709740337d2be52b031384f58Douglas Gregor  // after the top-level class is completely defined. Therefore, add
14416569d68745c8213709740337d2be52b031384f58Douglas Gregor  // it to the list of nested classes within its parent.
14426569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(CurScope->isClassScope() && "Nested class outside of class scope?");
14436569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.top()->NestedClasses.push_back(Victim);
14446569d68745c8213709740337d2be52b031384f58Douglas Gregor  Victim->TemplateScope = CurScope->getParent()->isTemplateParamScope();
14456569d68745c8213709740337d2be52b031384f58Douglas Gregor}
1446