ParseDeclCXX.cpp revision 334d47e92e9f241576fdeb7477b69a03136ba854
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"
1719510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
1819510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/Scope.h"
1919510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/ParsedTemplate.h"
20f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall#include "clang/Sema/PrettyDeclStackTrace.h"
21d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner#include "RAIIObjectsForParser.h"
228f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattnerusing namespace clang;
238f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner
248f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// ParseNamespace - We know that the current token is a namespace keyword. This
25d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// may either be a top level namespace or a block-level namespace alias. If
26d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// there was an inline keyword, it has already been parsed.
278f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
288f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       namespace-definition: [C++ 7.3: basic.namespace]
298f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         named-namespace-definition
308f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         unnamed-namespace-definition
318f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
328f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       unnamed-namespace-definition:
33d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' attributes[opt] '{' namespace-body '}'
348f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
358f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       named-namespace-definition:
368f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         original-namespace-definition
378f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         extension-namespace-definition
388f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
398f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       original-namespace-definition:
40d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' identifier attributes[opt]
41d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///             '{' namespace-body '}'
428f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
438f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       extension-namespace-definition:
44d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' original-namespace-name
45d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///             '{' namespace-body '}'
461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
478f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       namespace-alias-definition:  [C++ 7.3.2: namespace.alias]
488f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         'namespace' identifier '=' qualified-namespace-specifier ';'
498f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
50d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespace(unsigned Context,
51d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl                             SourceLocation &DeclEnd,
52d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl                             SourceLocation InlineLoc) {
5304d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
548f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation NamespaceLoc = ConsumeToken();  // eat the 'namespace'.
551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5649f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
5723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteNamespaceDecl(getCurScope());
58dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
5949f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
60193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
618f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation IdentLoc;
628f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  IdentifierInfo *Ident = 0;
636a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
646a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  Token attrTok;
651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6604d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  if (Tok.is(tok::identifier)) {
678f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    Ident = Tok.getIdentifierInfo();
688f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    IdentLoc = ConsumeToken();  // eat the identifier.
698f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  }
701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
718f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  // Read label attributes, if present.
721e37765c9257ef1d051f54a674eaa964bdba9693Ted Kremenek  llvm::OwningPtr<AttributeList> AttrList;
736a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::kw___attribute)) {
746a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor    attrTok = Tok;
756a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
768f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    // FIXME: save these somewhere.
771e37765c9257ef1d051f54a674eaa964bdba9693Ted Kremenek    AttrList.reset(ParseGNUAttributes());
786a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
806a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::equal)) {
816a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor    if (AttrList)
826a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor      Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
83d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl    if (InlineLoc.isValid())
84d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl      Diag(InlineLoc, diag::err_inline_namespace_alias)
85d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl          << FixItHint::CreateRemoval(InlineLoc);
866a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
8797144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
886a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
905144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  if (Tok.isNot(tok::l_brace)) {
911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Diag(Tok, Ident ? diag::err_expected_lbrace :
925144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner         diag::err_expected_ident_lbrace);
93d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
945144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  }
951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
965144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  SourceLocation LBrace = ConsumeBrace();
972d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
9823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() ||
9923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      getCurScope()->isInObjcMethodScope() || getCurScope()->getBlockParent() ||
10023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      getCurScope()->getFnParent()) {
10195f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor    Diag(LBrace, diag::err_namespace_nonnamespace_scope);
10295f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor    SkipUntil(tok::r_brace, false);
103d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
10495f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor  }
10595f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor
10688e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl  // If we're still good, complain about inline namespaces in non-C++0x now.
10788e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl  if (!getLang().CPlusPlus0x && InlineLoc.isValid())
10888e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl    Diag(InlineLoc, diag::ext_inline_namespace);
10988e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl
1105144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Enter a scope for the namespace.
1115144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  ParseScope NamespaceScope(this, Scope::DeclScope);
1122d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
113d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *NamespcDecl =
114d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl    Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, IdentLoc, Ident,
115d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl                                   LBrace, AttrList.get());
1162d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
117f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc,
118f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing namespace");
1191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
120bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
121bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    CXX0XAttributeList Attr;
122bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
123bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      Attr = ParseCXX0XAttributes();
124334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    if (getLang().Microsoft && Tok.is(tok::l_square))
125334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet      ParseMicrosoftAttributes();
126bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    ParseExternalDeclaration(Attr);
127bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1295144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Leave the namespace scope.
1305144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  NamespaceScope.Exit();
1318ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis
13297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBrace);
13397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  Actions.ActOnFinishNamespaceDef(NamespcDecl, RBraceLoc);
1342d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
13597144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = RBraceLoc;
1365144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  return NamespcDecl;
1378f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner}
138c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
139f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
140f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// alias definition.
141f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson///
142d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
1431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                              SourceLocation AliasLoc,
14497144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                              IdentifierInfo *Alias,
14597144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                              SourceLocation &DeclEnd) {
146f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  assert(Tok.is(tok::equal) && "Not equal token");
1471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
148f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  ConsumeToken(); // eat the '='.
1491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
15123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteNamespaceAliasDecl(getCurScope());
152dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
15349f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
154193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
155f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  CXXScopeSpec SS;
156f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse (optional) nested-name-specifier.
157b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
158f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
159f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
160f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    Diag(Tok, diag::err_expected_namespace_name);
161f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    // Skip to end of the definition and eat the ';'.
162f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    SkipUntil(tok::semi);
163d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
164f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  }
165f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
166f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse identifier.
16703bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  IdentifierInfo *Ident = Tok.getIdentifierInfo();
16803bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  SourceLocation IdentLoc = ConsumeToken();
1691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
170f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Eat the ';'.
17197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
1726869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name,
1736869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner                   "", tok::semi);
1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc, Alias,
17603bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson                                        SS, IdentLoc, Ident);
177f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson}
178f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
179c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal
180c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen.
181c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
182c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///       linkage-specification: [C++ 7.5p2: dcl.link]
183c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal '{' declaration-seq[opt] '}'
184c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal declaration
185c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
186d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseLinkage(ParsingDeclSpec &DS,
1873acd9aaa4ddd14afecb4f1c02ca6f585a6d51849Fariborz Jahanian                                       unsigned Context) {
188c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor  assert(Tok.is(tok::string_literal) && "Not a string literal!");
189193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  llvm::SmallString<8> LangBuffer;
190c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  // LangBuffer is guaranteed to be big enough.
191453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  bool Invalid = false;
192453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  llvm::StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid);
193453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  if (Invalid)
194d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
195c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
196c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  SourceLocation Loc = ConsumeStringToken();
197c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
198074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  ParseScope LinkageScope(this, Scope::DeclScope);
199d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *LinkageSpec
20023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    = Actions.ActOnStartLinkageSpecification(getCurScope(),
201074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                             /*FIXME: */SourceLocation(),
202d56638180014e60538cd666cd11fde6d4698e051Benjamin Kramer                                             Loc, Lang,
2031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                       Tok.is(tok::l_brace)? Tok.getLocation()
204074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                           : SourceLocation());
205074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
206bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  CXX0XAttributeList Attr;
207bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
208bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Attr = ParseCXX0XAttributes();
209bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
210334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  if (getLang().Microsoft && Tok.is(tok::l_square))
211334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    ParseMicrosoftAttributes();
212193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
213074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (Tok.isNot(tok::l_brace)) {
21435f9a196ef897b9559de25aaecd957208f0b4f59Abramo Bagnara    DS.setExternInLinkageSpec(true);
21509a63c97b95eb4dc6fd6b2323929e8cf12af03ffDouglas Gregor    ParseExternalDeclaration(Attr, &DS);
21623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
217074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                   SourceLocation());
2181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
219f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor
22063a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor  DS.abort();
22163a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor
222bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Attr.HasAttr)
223bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
224bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      << Attr.Range;
225bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
226f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  SourceLocation LBrace = ConsumeBrace();
227f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
228bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    CXX0XAttributeList Attr;
229bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
230bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      Attr = ParseCXX0XAttributes();
231334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    if (getLang().Microsoft && Tok.is(tok::l_square))
232334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet      ParseMicrosoftAttributes();
233bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    ParseExternalDeclaration(Attr);
234f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  }
235c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
236f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
23723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec, RBrace);
238c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner}
239e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
240f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
241f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'.
242d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
243bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                                     SourceLocation &DeclEnd,
244bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                                     CXX0XAttributeList Attr) {
245f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_using) && "Not using token");
246f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
247f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'using'.
248f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation UsingLoc = ConsumeToken();
249f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
25049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
25123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteUsing(getCurScope());
252dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
25349f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
254193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
2552f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner  if (Tok.is(tok::kw_namespace))
256f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // Next token after 'using' is 'namespace' so it must be using-directive
257bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return ParseUsingDirective(Context, UsingLoc, DeclEnd, Attr.AttrList);
258bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
259bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Attr.HasAttr)
260bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
261bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      << Attr.Range;
2622f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner
2632f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner  // Otherwise, it must be using-declaration.
264bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // Ignore illegal attributes (the caller should already have issued an error.
26597144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  return ParseUsingDeclaration(Context, UsingLoc, DeclEnd);
266f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
267f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
268f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes
269f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed.
270f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
271f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       using-directive: [C++ 7.3.p4: namespace.udir]
272f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
273f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name ;
274f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive:
275f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
276f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name attributes[opt] ;
277f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
278d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirective(unsigned Context,
27997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                              SourceLocation UsingLoc,
280bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                              SourceLocation &DeclEnd,
281bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                              AttributeList *Attr) {
282f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
283f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
284f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'namespace'.
285f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation NamespcLoc = ConsumeToken();
286f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
28749f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
28823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteUsingDirective(getCurScope());
289dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
29049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
291193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
292f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  CXXScopeSpec SS;
293f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse (optional) nested-name-specifier.
294b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
295f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
296f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  IdentifierInfo *NamespcName = 0;
297f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation IdentLoc = SourceLocation();
298f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
299f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse namespace-name.
300823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
301f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    Diag(Tok, diag::err_expected_namespace_name);
302f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // If there was invalid namespace name, skip to end of decl, and eat ';'.
303f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    SkipUntil(tok::semi);
304f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
305d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
306f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  }
3071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
308823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse identifier.
309823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  NamespcName = Tok.getIdentifierInfo();
310823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  IdentLoc = ConsumeToken();
3111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
312823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse (optional) attributes (most likely GNU strong-using extension).
313bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  bool GNUAttr = false;
314bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Tok.is(tok::kw___attribute)) {
315bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    GNUAttr = true;
316bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Attr = addAttributeLists(Attr, ParseGNUAttributes());
317bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
3181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
319823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Eat ';'.
32097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
3216869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi,
3229ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                   GNUAttr ? diag::err_expected_semi_after_attribute_list
3239ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                           : diag::err_expected_semi_after_namespace_name,
3249ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                   "", tok::semi);
325f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
32623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
327bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                      IdentLoc, NamespcName, Attr);
328f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
329f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
330f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that
331f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' was already seen.
332f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
333f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///     using-declaration: [C++ 7.3.p3: namespace.udecl]
334f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       'using' 'typename'[opt] ::[opt] nested-name-specifier
3359cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///               unqualified-id
3369cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///       'using' :: unqualified-id
337f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
338d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDeclaration(unsigned Context,
33997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                                SourceLocation UsingLoc,
340595adc1795cc2c079ef5876100e01acd10a0504aAnders Carlsson                                                SourceLocation &DeclEnd,
341595adc1795cc2c079ef5876100e01acd10a0504aAnders Carlsson                                                AccessSpecifier AS) {
3429cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  CXXScopeSpec SS;
3437ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall  SourceLocation TypenameLoc;
3449cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  bool IsTypeName;
3459cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3469cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Ignore optional 'typename'.
34712c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // FIXME: This is wrong; we should parse this as a typename-specifier.
3489cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_typename)) {
3497ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall    TypenameLoc = Tok.getLocation();
3509cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    ConsumeToken();
3519cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = true;
3529cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
3539cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  else
3549cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = false;
3559cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3569cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Parse nested-name-specifier.
357b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
3589cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3599cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Check nested-name specifier.
3609cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (SS.isInvalid()) {
3619cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
362d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
3639cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
365193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  // Parse the unqualified-id. We allow parsing of both constructor and
36612c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // destructor names and allow the action module to diagnose any semantic
36712c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // errors.
36812c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  UnqualifiedId Name;
369193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  if (ParseUnqualifiedId(SS,
37012c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*EnteringContext=*/false,
37112c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*AllowDestructorName=*/true,
372193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                         /*AllowConstructorName=*/true,
373b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                         ParsedType(),
37412c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         Name)) {
3759cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
376d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
3779cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
378193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
3799cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Parse (optional) attributes (most likely GNU strong-using extension).
3801e37765c9257ef1d051f54a674eaa964bdba9693Ted Kremenek  llvm::OwningPtr<AttributeList> AttrList;
3819cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw___attribute))
3821e37765c9257ef1d051f54a674eaa964bdba9693Ted Kremenek    AttrList.reset(ParseGNUAttributes());
3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3849cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Eat ';'.
3859cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  DeclEnd = Tok.getLocation();
3869cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
387193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                   AttrList ? "attributes list" : "using declaration",
38812c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                   tok::semi);
3899cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
39023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS, Name,
3911e37765c9257ef1d051f54a674eaa964bdba9693Ted Kremenek                                       AttrList.get(), IsTypeName, TypenameLoc);
392f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
393f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
394511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
395511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
396511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///      static_assert-declaration:
397511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///        static_assert ( constant-expression  ,  string-literal  ) ;
398511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
399d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
400511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
401511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation StaticAssertLoc = ConsumeToken();
4021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
403511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (Tok.isNot(tok::l_paren)) {
404511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_lparen);
405d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
406511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
4071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
408511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation LParenLoc = ConsumeParen();
409e0762c92110dfdcdd207db461a4ea17afd168f1eDouglas Gregor
41060d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult AssertExpr(ParseConstantExpression());
411511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (AssertExpr.isInvalid()) {
412511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    SkipUntil(tok::semi);
413d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
414511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
4151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
416ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
417d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
418ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson
419511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (Tok.isNot(tok::string_literal)) {
420511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_string_literal);
421511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    SkipUntil(tok::semi);
422d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
423511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42560d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult AssertMessage(ParseStringLiteralExpression());
4261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (AssertMessage.isInvalid())
427d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
428511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
42994b15fbc3a10cdfb1639528a8a773b66a1e7cd9eAnders Carlsson  MatchRHSPunctuation(tok::r_paren, LParenLoc);
4301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
43197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
4329ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor  ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert);
433511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
4349ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc,
4359ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                              AssertExpr.take(),
4369ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                              AssertMessage.take());
437511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson}
438511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
4396fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// ParseDecltypeSpecifier - Parse a C++0x decltype specifier.
4406fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
4416fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 'decltype' ( expression )
4426fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
4436fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlssonvoid Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
4446fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  assert(Tok.is(tok::kw_decltype) && "Not a decltype specifier");
4456fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
4466fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation StartLoc = ConsumeToken();
4476fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation LParenLoc = Tok.getLocation();
4481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
4506fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson                       "decltype")) {
4516fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    SkipUntil(tok::r_paren);
4526fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
4536fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  }
4541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4556fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Parse the expression
4561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4576fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // C++0x [dcl.type.simple]p4:
4586fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  //   The operand of the decltype specifier is an unevaluated operand.
4596fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  EnterExpressionEvaluationContext Unevaluated(Actions,
460f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                               Sema::Unevaluated);
46160d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Result = ParseExpression();
4626fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (Result.isInvalid()) {
4636fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    SkipUntil(tok::r_paren);
4646fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
4656fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  }
4661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4676fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Match the ')'
4686fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation RParenLoc;
4696fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (Tok.is(tok::r_paren))
4706fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    RParenLoc = ConsumeParen();
4716fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  else
4726fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    MatchRHSPunctuation(tok::r_paren, LParenLoc);
4731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4746fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (RParenLoc.isInvalid())
4756fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
4766fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
4776fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  const char *PrevSpec = 0;
478fec54013fcd0eb72642741584ca04c1bc292bef8John McCall  unsigned DiagID;
4796fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Check for duplicate type specifiers (e.g. "int decltype(a)").
4801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec,
481fec54013fcd0eb72642741584ca04c1bc292bef8John McCall                         DiagID, Result.release()))
482fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
4836fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson}
4846fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
48542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// ParseClassName - Parse a C++ class-name, which names a class. Note
48642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// that we only check that the result names a type; semantic analysis
48742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// will need to verify that the type names a class. The result is
4887f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor/// either a type or NULL, depending on whether a type name was
48942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// found.
49042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///
49142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///       class-name: [C++ 9.1]
49242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///         identifier
4937f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor///         simple-template-id
4941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
49531a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas GregorParser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
4969ab14541716928894821cf5d53d6b4c95ffdf3a3Jeffrey Yasskin                                          CXXScopeSpec *SS) {
4977f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  // Check whether we have a template-id that names a type.
4987f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  if (Tok.is(tok::annot_template_id)) {
4991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    TemplateIdAnnotation *TemplateId
5007f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
501d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor    if (TemplateId->Kind == TNK_Type_template ||
502d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor        TemplateId->Kind == TNK_Dependent_template_name) {
50331a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      AnnotateTemplateIdTokenAsType(SS);
5047f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
5057f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
506b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      ParsedType Type = getTypeAnnotation(Tok);
5077f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      EndLocation = Tok.getAnnotationEndLoc();
5087f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      ConsumeToken();
50931a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor
51031a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      if (Type)
51131a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor        return Type;
51231a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      return true;
5137f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    }
5147f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
5157f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    // Fall through to produce an error below.
5167f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  }
5177f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
51842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  if (Tok.isNot(tok::identifier)) {
5191ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_class_name);
52031a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
52142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
52242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
52384d0a19828599e8623223632d59447fd498999cfDouglas Gregor  IdentifierInfo *Id = Tok.getIdentifierInfo();
52484d0a19828599e8623223632d59447fd498999cfDouglas Gregor  SourceLocation IdLoc = ConsumeToken();
52584d0a19828599e8623223632d59447fd498999cfDouglas Gregor
52684d0a19828599e8623223632d59447fd498999cfDouglas Gregor  if (Tok.is(tok::less)) {
52784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // It looks the user intended to write a template-id here, but the
52884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // template-name was wrong. Try to fix that.
52984d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateNameKind TNK = TNK_Type_template;
53084d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateTy Template;
53123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(),
53284d0a19828599e8623223632d59447fd498999cfDouglas Gregor                                             SS, Template, TNK)) {
53384d0a19828599e8623223632d59447fd498999cfDouglas Gregor      Diag(IdLoc, diag::err_unknown_template_name)
53484d0a19828599e8623223632d59447fd498999cfDouglas Gregor        << Id;
53584d0a19828599e8623223632d59447fd498999cfDouglas Gregor    }
536193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
53784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (!Template)
53884d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
53984d0a19828599e8623223632d59447fd498999cfDouglas Gregor
540193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam    // Form the template name
54184d0a19828599e8623223632d59447fd498999cfDouglas Gregor    UnqualifiedId TemplateName;
54284d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateName.setIdentifier(Id, IdLoc);
543193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
54484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // Parse the full template-id, then turn it into a type.
54584d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName,
54684d0a19828599e8623223632d59447fd498999cfDouglas Gregor                                SourceLocation(), true))
54784d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
54884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (TNK == TNK_Dependent_template_name)
54984d0a19828599e8623223632d59447fd498999cfDouglas Gregor      AnnotateTemplateIdTokenAsType(SS);
550193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
55184d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // If we didn't end up with a typename token, there's nothing more we
55284d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // can do.
55384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (Tok.isNot(tok::annot_typename))
55484d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
555193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
55684d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // Retrieve the type from the annotation token, consume that token, and
55784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // return.
55884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    EndLocation = Tok.getAnnotationEndLoc();
559b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    ParsedType Type = getTypeAnnotation(Tok);
56084d0a19828599e8623223632d59447fd498999cfDouglas Gregor    ConsumeToken();
56184d0a19828599e8623223632d59447fd498999cfDouglas Gregor    return Type;
56284d0a19828599e8623223632d59447fd498999cfDouglas Gregor  }
56384d0a19828599e8623223632d59447fd498999cfDouglas Gregor
56442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // We have an identifier; check whether it is actually a type.
565b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), SS, true);
566193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  if (!Type) {
567124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor    Diag(IdLoc, diag::err_expected_class_name);
56831a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
56942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
57042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
57142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Consume the identifier.
57284d0a19828599e8623223632d59447fd498999cfDouglas Gregor  EndLocation = IdLoc;
5735606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
5745606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  // Fake up a Declarator to use with ActOnTypeName.
5755606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DeclSpec DS;
5765606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetRangeStart(IdLoc);
5775606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetRangeEnd(EndLocation);
5785606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.getTypeSpecScope() = *SS;
5795606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
5805606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  const char *PrevSpec = 0;
5815606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  unsigned DiagID;
5825606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type);
5835606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
5845606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
5855606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
58642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor}
58742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
588e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
589e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
590e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that
591d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl/// cannot start a definition. If SuppressDeclarations is true, we do know.
592e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
593e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-specifier: [C++ class]
594e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}'
595e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}' attributes[opt]
596e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-head:
597e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key identifier[opt] base-clause[opt]
598e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier identifier base-clause[opt]
599e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier[opt] simple-template-id
600e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          base-clause[opt]
601e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   class-key attributes[opt] identifier[opt] base-clause[opt]
6021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier
603e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          identifier base-clause[opt]
6041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier[opt]
605e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          simple-template-id base-clause[opt]
606e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-key:
607e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'class'
608e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
609e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
610e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
611e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       elaborated-type-specifier: [C++ dcl.type.elab]
6121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] identifier
6131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
6141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///                          simple-template-id
615e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
616e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  Note that the C++ class-specifier and elaborated-type-specifier,
617e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  together, subsume the C99 struct-or-union-specifier:
618e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
619e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union-specifier: [C99 6.7.2.1]
620e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier[opt] '{' struct-contents '}'
621e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier
622e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier[opt] '{' struct-contents
623e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                                                         '}' attributes[opt]
624e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier
625e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union:
626e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
627e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
6284c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattnervoid Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
6294c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner                                 SourceLocation StartLoc, DeclSpec &DS,
6304d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                 const ParsedTemplateInfo &TemplateInfo,
631d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl                                 AccessSpecifier AS, bool SuppressDeclarations){
6324c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  DeclSpec::TST TagType;
6334c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  if (TagTokKind == tok::kw_struct)
6344c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_struct;
6354c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  else if (TagTokKind == tok::kw_class)
6364c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_class;
6374c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  else {
6384c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    assert(TagTokKind == tok::kw_union && "Not a class specifier");
6394c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_union;
6404c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  }
641e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
642374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  if (Tok.is(tok::code_completion)) {
643374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor    // Code completion for a struct, class, or union name.
64423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteTag(getCurScope(), TagType);
645dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
646374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  }
647193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
648926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // C++03 [temp.explicit] 14.7.2/8:
649926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //   The usual access checking rules do not apply to names used to specify
650926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //   explicit instantiations.
651926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //
652926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // As an extension we do not perform access checking on the names used to
653926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // specify explicit specializations either. This is important to allow
654926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // specializing traits classes for private types.
655926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  bool SuppressingAccessChecks = false;
656926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
657926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth      TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization) {
658926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth    Actions.ActOnStartSuppressingAccessChecks();
659926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth    SuppressingAccessChecks = true;
660926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  }
661926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
662bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  AttributeList *AttrList = 0;
663e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If attributes exist after tag, parse them.
664e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw___attribute))
665bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = ParseGNUAttributes();
666e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
667f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff  // If declspecs exist after tag, parse them.
668b1d397c23e1f8fd8b404d5731d531e7500f7140dJohn McCall  while (Tok.is(tok::kw___declspec))
669bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = ParseMicrosoftDeclSpec(AttrList);
670193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
671bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // If C++0x attributes exist here, parse them.
672bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Are we consistent with the ordering of parsing of different
673bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // styles of attributes?
674bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (isCXX0XAttributeSpecifier())
675bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = addAttributeLists(AttrList, ParseCXX0XAttributes().AttrList);
6761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
677b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_pod)) {
678b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // GNU libstdc++ 4.2 uses __is_pod as the name of a struct template, but
679b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // __is_pod is a keyword in GCC >= 4.3. Therefore, when we see the
6801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // token sequence "struct __is_pod", make __is_pod into a normal
681b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // identifier rather than a keyword, to allow libstdc++ 4.2 to work
682b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // properly.
683646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
684b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.setKind(tok::identifier);
685b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  }
686b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor
687b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_empty)) {
688b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // GNU libstdc++ 4.2 uses __is_empty as the name of a struct template, but
689b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // __is_empty is a keyword in GCC >= 4.3. Therefore, when we see the
6901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // token sequence "struct __is_empty", make __is_empty into a normal
691b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // identifier rather than a keyword, to allow libstdc++ 4.2 to work
692b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // properly.
693646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
694b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.setKind(tok::identifier);
695b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  }
6961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
697eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse the (optional) nested-name-specifier.
698aa87d33309f505b68c3bfc17486c93e4d224b24fJohn McCall  CXXScopeSpec &SS = DS.getTypeSpecScope();
69908d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  if (getLang().CPlusPlus) {
70008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    // "FOO : BAR" is not a potential typo for "FOO::BAR".
70108d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    ColonProtectionRAIIObject X(*this);
702193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
703b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), true))
704207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      DS.SetTypeSpecError();
7059ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall    if (SS.isSet())
70608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner      if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
70708d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner        Diag(Tok, diag::err_expected_ident);
70808d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  }
709cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
7102cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor  TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
7112cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor
712cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  // Parse the (optional) class name or simple-template-id.
713e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  IdentifierInfo *Name = 0;
714e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation NameLoc;
71539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  TemplateIdAnnotation *TemplateId = 0;
716e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::identifier)) {
717e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    Name = Tok.getIdentifierInfo();
718e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    NameLoc = ConsumeToken();
719193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
7205ee3734c0b5222a7c445591a1f14102c1b3a289bDouglas Gregor    if (Tok.is(tok::less) && getLang().CPlusPlus) {
721193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      // The name was supposed to refer to a template, but didn't.
7222cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // Eat the template argument list and try to continue parsing this as
7232cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // a class (or template thereof).
7242cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      TemplateArgList TemplateArgs;
7252cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      SourceLocation LAngleLoc, RAngleLoc;
726193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, &SS,
7272cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor                                           true, LAngleLoc,
728314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor                                           TemplateArgs, RAngleLoc)) {
7292cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // We couldn't parse the template argument list at all, so don't
7302cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // try to give any location information for the list.
7312cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        LAngleLoc = RAngleLoc = SourceLocation();
7322cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
733193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
7342cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      Diag(NameLoc, diag::err_explicit_spec_non_template)
735c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
7362cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << (TagType == DeclSpec::TST_class? 0
7372cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor            : TagType == DeclSpec::TST_struct? 1
7382cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor            : 2)
7392cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << Name
7402cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << SourceRange(LAngleLoc, RAngleLoc);
741193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
742193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      // Strip off the last template parameter list if it was empty, since
743c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      // we've removed its template argument list.
744c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
745c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        if (TemplateParams && TemplateParams->size() > 1) {
746c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams->pop_back();
747c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        } else {
748c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams = 0;
749193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam          const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
750c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor            = ParsedTemplateInfo::NonTemplate;
751c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        }
752c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      } else if (TemplateInfo.Kind
753c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor                                == ParsedTemplateInfo::ExplicitInstantiation) {
754c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        // Pretend this is just a forward declaration.
7552cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        TemplateParams = 0;
756193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam        const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
7572cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor          = ParsedTemplateInfo::NonTemplate;
758193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam        const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc
759c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
760c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc
761c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
7622cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
7632cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor    }
76439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  } else if (Tok.is(tok::annot_template_id)) {
76539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
76639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    NameLoc = ConsumeToken();
767cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
768c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor    if (TemplateId->Kind != TNK_Type_template) {
76939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // The template-name in the simple-template-id refers to
77039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // something other than a class template. Give an appropriate
77139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // error message and skip to the ';'.
77239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SourceRange Range(NameLoc);
77339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      if (SS.isNotEmpty())
77439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        Range.setBegin(SS.getBeginLoc());
77539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
77639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
77739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        << Name << static_cast<int>(TemplateId->Kind) << Range;
7781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
77939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      DS.SetTypeSpecError();
78039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SkipUntil(tok::semi, false, true);
78139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      TemplateId->Destroy();
782926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth      if (SuppressingAccessChecks)
783926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth        Actions.ActOnStopSuppressingAccessChecks();
784926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
78539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      return;
786cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    }
787e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
788e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
789926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // As soon as we're finished parsing the class's template-id, turn access
790926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // checking back on.
791926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  if (SuppressingAccessChecks)
792926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth    Actions.ActOnStopSuppressingAccessChecks();
793926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
79467d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  // There are four options here.  If we have 'struct foo;', then this
79567d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  // is either a forward declaration or a friend declaration, which
79667d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  // have to be treated differently.  If we have 'struct foo {...' or
79739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  // 'struct foo :...' then this is a definition. Otherwise we have
798e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // something like 'struct foo xyz', a reference.
799d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // However, in some contexts, things look like declarations but are just
800d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // references, e.g.
801d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // new struct s;
802d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // or
803d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // &T::operator struct s;
804d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // For these, SuppressDeclarations is true.
805f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  Sema::TagUseKind TUK;
806d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  if (SuppressDeclarations)
807f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = Sema::TUK_Reference;
808d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  else if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))){
809d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    if (DS.isFriendSpecified()) {
810d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // C++ [class.friend]p2:
811d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      //   A class shall not be defined in a friend declaration.
812d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      Diag(Tok.getLocation(), diag::err_friend_decl_defines_class)
813d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor        << SourceRange(DS.getFriendSpecLoc());
814d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor
815d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Skip everything up to the semicolon, so that this looks like a proper
816d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // friend class (or template thereof) declaration.
817d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      SkipUntil(tok::semi, true, true);
818f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall      TUK = Sema::TUK_Friend;
819d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    } else {
820d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Okay, this is a class definition.
821f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall      TUK = Sema::TUK_Definition;
822d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    }
823d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor  } else if (Tok.is(tok::semi))
824f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
825e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  else
826f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = Sema::TUK_Reference;
827e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
828207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall  if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error ||
829f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                               TUK != Sema::TUK_Definition)) {
830207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall    if (DS.getTypeSpecType() != DeclSpec::TST_error) {
831207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      // We have a declaration or reference to an anonymous class.
832207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      Diag(StartLoc, diag::err_anon_type_definition)
833207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall        << DeclSpec::getSpecifierName(TagType);
834207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall    }
835e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
836e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SkipUntil(tok::comma, true);
83739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
83839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    if (TemplateId)
83939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      TemplateId->Destroy();
840e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    return;
841e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
842e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
843ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  // Create the tag portion of the class or class template.
844d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  DeclResult TagOrTempResult = true; // invalid
845d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  TypeResult TypeResult = true; // invalid
8464d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
847402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor  bool Owned = false;
848f1bbbb49f06a7462476cd88166fccda5feb15cabJohn McCall  if (TemplateId) {
8494d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // Explicit specialization, class template partial specialization,
8504d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // or explicit instantiation.
8511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ASTTemplateArgsPtr TemplateArgsPtr(Actions,
85239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->getTemplateArgs(),
85339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->NumArgs);
8544d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
855f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        TUK == Sema::TUK_Declaration) {
8564d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit instantiation of a class template.
8574d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
85823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        = Actions.ActOnExplicitInstantiation(getCurScope(),
85945f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                             TemplateInfo.ExternLoc,
8601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateInfo.TemplateLoc,
8614d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TagType,
8621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             StartLoc,
8634d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             SS,
8642b5289b6fd7e3d9899868410a498c081c9595662John McCall                                             TemplateId->Template,
8651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->TemplateNameLoc,
8661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->LAngleLoc,
8674d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateArgsPtr,
8681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->RAngleLoc,
869bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                             AttrList);
87074256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall
87174256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // Friend template-ids are treated as references unless
87274256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // they have template headers, in which case they're ill-formed
87374256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // (FIXME: "template <class T> friend class A<T>::B<int>;").
87474256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // We diagnose this error in ActOnClassTemplateSpecialization.
875f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    } else if (TUK == Sema::TUK_Reference ||
876f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall               (TUK == Sema::TUK_Friend &&
87774256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall                TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
878c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall      TypeResult
8792b5289b6fd7e3d9899868410a498c081c9595662John McCall        = Actions.ActOnTemplateIdType(TemplateId->Template,
8806b2becfc434b0bdced8560802c4d0e03148c61b8John McCall                                      TemplateId->TemplateNameLoc,
8816b2becfc434b0bdced8560802c4d0e03148c61b8John McCall                                      TemplateId->LAngleLoc,
8826b2becfc434b0bdced8560802c4d0e03148c61b8John McCall                                      TemplateArgsPtr,
8836b2becfc434b0bdced8560802c4d0e03148c61b8John McCall                                      TemplateId->RAngleLoc);
8846b2becfc434b0bdced8560802c4d0e03148c61b8John McCall
885c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall      TypeResult = Actions.ActOnTagTemplateIdType(TypeResult, TUK,
886c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall                                                  TagType, StartLoc);
8874d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    } else {
8884d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit specialization or a class template
8894d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // partial specialization.
8904d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TemplateParameterLists FakedParamLists;
8914d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
8924d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
8934d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // This looks like an explicit instantiation, because we have
8944d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // something like
8954d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
8964d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //   template class Foo<X>
8974d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
8983f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor        // but it actually has a definition. Most likely, this was
8994d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // meant to be an explicit specialization, but the user forgot
9004d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // the '<>' after 'template'.
901f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        assert(TUK == Sema::TUK_Definition && "Expected a definition here");
9024d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
9031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        SourceLocation LAngleLoc
9044d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
9051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        Diag(TemplateId->TemplateNameLoc,
9064d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor             diag::err_explicit_instantiation_with_definition)
9074d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          << SourceRange(TemplateInfo.TemplateLoc)
908849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor          << FixItHint::CreateInsertion(LAngleLoc, "<>");
9094d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
9104d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // Create a fake template parameter list that contains only
9114d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // "template<>", so that we treat this construct as a class
9124d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // template specialization.
9134d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        FakedParamLists.push_back(
9141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          Actions.ActOnTemplateParameterList(0, SourceLocation(),
9154d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateInfo.TemplateLoc,
9161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             LAngleLoc,
9171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             0, 0,
9184d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             LAngleLoc));
9194d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        TemplateParams = &FakedParamLists;
9204d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      }
9214d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
9224d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // Build the class template specialization.
9234d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
92423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK,
92539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       StartLoc, SS,
9262b5289b6fd7e3d9899868410a498c081c9595662John McCall                       TemplateId->Template,
9271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->TemplateNameLoc,
9281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->LAngleLoc,
92939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       TemplateArgsPtr,
9301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->RAngleLoc,
931bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                       AttrList,
932f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                       MultiTemplateParamsArg(Actions,
933cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                    TemplateParams? &(*TemplateParams)[0] : 0,
934cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                 TemplateParams? TemplateParams->size() : 0));
9354d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    }
93639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    TemplateId->Destroy();
9373f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
938f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall             TUK == Sema::TUK_Declaration) {
9393f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Explicit instantiation of a member of a class template
9403f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // specialization, e.g.,
9413f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
9423f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //   template struct Outer<int>::Inner;
9433f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
9443f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    TagOrTempResult
94523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      = Actions.ActOnExplicitInstantiation(getCurScope(),
94645f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                           TemplateInfo.ExternLoc,
9471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TemplateInfo.TemplateLoc,
9481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TagType, StartLoc, SS, Name,
949bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                           NameLoc, AttrList);
9503f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else {
9513f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
952f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        TUK == Sema::TUK_Definition) {
9533f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor      // FIXME: Diagnose this particular error.
9543f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    }
9553f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor
956c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    bool IsDependent = false;
957c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
9583f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Declaration or definition of a class type
95923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc, SS,
960bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                       Name, NameLoc, AttrList, AS,
961f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                       MultiTemplateParamsArg(Actions,
9627cdbc5832084f45721693dfb1d93284c3e08efeeDouglas Gregor                                    TemplateParams? &(*TemplateParams)[0] : 0,
9637cdbc5832084f45721693dfb1d93284c3e08efeeDouglas Gregor                                    TemplateParams? TemplateParams->size() : 0),
9641274ccd90aec0b205fc838c3d504821ccfb55482Douglas Gregor                                       Owned, IsDependent, false,
9651274ccd90aec0b205fc838c3d504821ccfb55482Douglas Gregor                                       clang::TypeResult());
966c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
967c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // If ActOnTag said the type was dependent, try again with the
968c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // less common call.
969c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    if (IsDependent)
97023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK,
971193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                                             SS, Name, StartLoc, NameLoc);
9723f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  }
973e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
974e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If there is a body, parse it and inform the actions module.
975f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  if (TUK == Sema::TUK_Definition) {
976bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    assert(Tok.is(tok::l_brace) ||
977bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall           (getLang().CPlusPlus && Tok.is(tok::colon)));
97807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    if (getLang().CPlusPlus)
979212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
98007952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    else
981212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
982e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
983e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
984b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  // FIXME: The DeclSpec should keep the locations of both the keyword and the
985b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  // name (if there is one).
986b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc;
987b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall
988b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  const char *PrevSpec = 0;
989b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  unsigned DiagID;
990b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  bool Result;
991c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  if (!TypeResult.isInvalid()) {
992b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    Result = DS.SetTypeSpecType(DeclSpec::TST_typename, TSTLoc,
993b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                PrevSpec, DiagID, TypeResult.get());
994c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else if (!TagOrTempResult.isInvalid()) {
995b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    Result = DS.SetTypeSpecType(TagType, TSTLoc, PrevSpec, DiagID,
996b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                TagOrTempResult.get(), Owned);
997c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else {
998ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    DS.SetTypeSpecError();
99966e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson    return;
100066e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson  }
10011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1002b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  if (Result)
1003fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
1004193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
10054ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // At this point, we've successfully parsed a class-specifier in 'definition'
10064ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // form (e.g. "struct foo { int x; }".  While we could just return here, we're
10074ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // going to look at what comes after it to improve error recovery.  If an
10084ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // impossible token occurs next, we assume that the programmer forgot a ; at
10094ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // the end of the declaration and recover that way.
10104ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  //
10114ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // This switch enumerates the valid "follow" set for definition.
1012f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  if (TUK == Sema::TUK_Definition) {
1013b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    bool ExpectedSemi = true;
10144ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    switch (Tok.getKind()) {
1015b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    default: break;
10164ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    case tok::semi:               // struct foo {...} ;
101799c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::star:               // struct foo {...} *         P;
101899c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::amp:                // struct foo {...} &         R = ...
101999c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::identifier:         // struct foo {...} V         ;
102099c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::r_paren:            //(struct foo {...} )         {4}
102199c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_cxxscope:     // struct foo {...} a::       b;
102299c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_typename:     // struct foo {...} a         ::b;
102399c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_template_id:  // struct foo {...} a<int>    ::b;
1024c2e1c1af8ffe750b827284f207b9207112c7cc4eChris Lattner    case tok::l_paren:            // struct foo {...} (         x);
102516acfee729e00536af827935ccfcf69be721e462Chris Lattner    case tok::comma:              // __builtin_offsetof(struct foo{...} ,
1026b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      ExpectedSemi = false;
1027b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      break;
1028b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    // Type qualifiers
1029b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_const:           // struct foo {...} const     x;
1030b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_volatile:        // struct foo {...} volatile  x;
1031b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_restrict:        // struct foo {...} restrict  x;
1032b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_inline:          // struct foo {...} inline    foo() {};
103399c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    // Storage-class specifiers
103499c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_static:          // struct foo {...} static    x;
103599c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_extern:          // struct foo {...} extern    x;
103699c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_typedef:         // struct foo {...} typedef   x;
103799c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_register:        // struct foo {...} register  x;
103899c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_auto:            // struct foo {...} auto      x;
103933f992425213f381fc503699b26ee8cf9b60494eDouglas Gregor    case tok::kw_mutable:         // struct foo {...} mutable      x;
1040b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // As shown above, type qualifiers and storage class specifiers absolutely
1041b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // can occur after class specifiers according to the grammar.  However,
1042b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // almost noone actually writes code like this.  If we see one of these,
1043b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // it is much more likely that someone missed a semi colon and the
1044b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // type/storage class specifier we're seeing is part of the *next*
1045b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // intended declaration, as in:
1046b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //
1047b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //   struct foo { ... }
1048b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //   typedef int X;
1049b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //
1050b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // We'd really like to emit a missing semicolon error instead of emitting
1051b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // an error on the 'int' saying that you can't have two type specifiers in
1052b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // the same declaration of X.  Because of this, we look ahead past this
1053b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // token to see if it's a type specifier.  If so, we know the code is
1054b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // otherwise invalid, so we can produce the expected semi error.
1055b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      if (!isKnownToBeTypeSpecifier(NextToken()))
1056b3a4e432c90be98c6d918087750397e86d030368Chris Lattner        ExpectedSemi = false;
10574ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      break;
1058193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1059193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam    case tok::r_brace:  // struct bar { struct foo {...} }
10604ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // Missing ';' at end of struct is accepted as an extension in C mode.
1061b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      if (!getLang().CPlusPlus)
1062b3a4e432c90be98c6d918087750397e86d030368Chris Lattner        ExpectedSemi = false;
1063b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      break;
1064b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    }
1065193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1066b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    if (ExpectedSemi) {
10674ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
10684ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner                       TagType == DeclSpec::TST_class ? "class"
10694ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner                       : TagType == DeclSpec::TST_struct? "struct" : "union");
10704ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // Push this token back into the preprocessor and change our current token
10714ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // to ';' so that the rest of the code recovers as though there were an
10724ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // ';' after the definition.
10734ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      PP.EnterToken(Tok);
1074193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      Tok.setKind(tok::semi);
10754ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    }
10764ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  }
1077e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1078e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
10791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
1080e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1081e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-clause : [C++ class.derived]
1082e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ':' base-specifier-list
1083e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier-list:
1084e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier '...'[opt]
1085e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier-list ',' base-specifier '...'[opt]
1086d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseBaseClause(Decl *ClassDecl) {
1087e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  assert(Tok.is(tok::colon) && "Not a base clause");
1088e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  ConsumeToken();
1089e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1090f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Build up an array of parsed base specifiers.
1091ca0408fb49c1370430672acf2d770b7151cf71deJohn McCall  llvm::SmallVector<CXXBaseSpecifier *, 8> BaseInfo;
1092f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
1093e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  while (true) {
1094e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Parse a base-specifier.
1095f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    BaseResult Result = ParseBaseSpecifier(ClassDecl);
10965ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor    if (Result.isInvalid()) {
1097e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Skip the rest of this base specifier, up until the comma or
1098e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // opening brace.
1099f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      SkipUntil(tok::comma, tok::l_brace, true, true);
1100f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    } else {
1101f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      // Add this to our array of base specifiers.
11025ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor      BaseInfo.push_back(Result.get());
1103e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
1104e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1105e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // If the next token is a comma, consume it and keep reading
1106e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // base-specifiers.
1107e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (Tok.isNot(tok::comma)) break;
11081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1109e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Consume the comma.
1110e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
1111e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1112f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
1113f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Attach the base specifiers
1114beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad  Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size());
1115e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1116e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1117e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
1118e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example:
1119e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///    class foo : public bar, virtual private baz {
1120e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers.
1121e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1122e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier: [C++ class.derived]
1123e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ::[opt] nested-name-specifier[opt] class-name
1124e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt]
1125e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                        class-name
1126e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
1127e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                        class-name
1128d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {
1129e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  bool IsVirtual = false;
1130e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation StartLoc = Tok.getLocation();
1131e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1132e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword.
1133e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
1134e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
1135e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
1136e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1137e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1138e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse an (optional) access specifier.
1139e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  AccessSpecifier Access = getAccessSpecifierIfPresent();
114092f883177b162928a8e632e4e3b93fafd2b26072John McCall  if (Access != AS_none)
1141e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
11421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1143e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword (again!), in case it came after the
1144e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // access specifier.
1145e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
1146e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SourceLocation VirtualLoc = ConsumeToken();
1147e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (IsVirtual) {
1148e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Complain about duplicate 'virtual'
11491ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner      Diag(VirtualLoc, diag::err_dup_virtual)
1150849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor        << FixItHint::CreateRemoval(VirtualLoc);
1151e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
1152e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1153e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
1154e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1155e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1156eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse optional '::' and optional nested-name-specifier.
1157eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  CXXScopeSpec SS;
1158b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
1159e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1160e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // The location of the base class itself.
1161e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation BaseLoc = Tok.getLocation();
116242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
116342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Parse the class-name.
11647f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceLocation EndLocation;
116531a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor  TypeResult BaseType = ParseClassName(EndLocation, &SS);
116631a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor  if (BaseType.isInvalid())
116742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor    return true;
11681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Find the complete source range for the base-specifier.
11707f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceRange Range(StartLoc, EndLocation);
11711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1172e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Notify semantic analysis that we have parsed a complete
1173e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // base-specifier.
1174a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl  return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
117531a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor                                    BaseType.get(), BaseLoc);
1176e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1177e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1178e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is
1179e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier.
1180e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1181e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       access-specifier: [C++ class.derived]
1182e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'private'
1183e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'protected'
1184e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'public'
11851eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAccessSpecifier Parser::getAccessSpecifierIfPresent() const {
1186e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  switch (Tok.getKind()) {
1187e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  default: return AS_none;
1188e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_private: return AS_private;
1189e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_protected: return AS_protected;
1190e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_public: return AS_public;
1191e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1192e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
11934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1194d33133cdc1af466f9c276249b2621be03867888bEli Friedmanvoid Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
1195d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall                                             Decl *ThisDecl) {
1196d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // We just declared a member function. If this member function
1197d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // has any default arguments, we'll need to parse them later.
1198d33133cdc1af466f9c276249b2621be03867888bEli Friedman  LateParsedMethodDeclaration *LateMethod = 0;
11991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  DeclaratorChunk::FunctionTypeInfo &FTI
1200d33133cdc1af466f9c276249b2621be03867888bEli Friedman    = DeclaratorInfo.getTypeObject(0).Fun;
1201d33133cdc1af466f9c276249b2621be03867888bEli Friedman  for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
1202d33133cdc1af466f9c276249b2621be03867888bEli Friedman    if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
1203d33133cdc1af466f9c276249b2621be03867888bEli Friedman      if (!LateMethod) {
1204d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Push this method onto the stack of late-parsed method
1205d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // declarations.
1206d33133cdc1af466f9c276249b2621be03867888bEli Friedman        getCurrentClass().MethodDecls.push_back(
1207d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                LateParsedMethodDeclaration(ThisDecl));
1208d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateMethod = &getCurrentClass().MethodDecls.back();
120923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        LateMethod->TemplateScope = getCurScope()->isTemplateParamScope();
1210d33133cdc1af466f9c276249b2621be03867888bEli Friedman
1211d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Add all of the parameters prior to this one (they don't
1212d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // have default arguments).
1213d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateMethod->DefaultArgs.reserve(FTI.NumArgs);
1214d33133cdc1af466f9c276249b2621be03867888bEli Friedman        for (unsigned I = 0; I < ParamIdx; ++I)
1215d33133cdc1af466f9c276249b2621be03867888bEli Friedman          LateMethod->DefaultArgs.push_back(
12168f8210c47797f013e0fb24a26f9c4751b10783feDouglas Gregor                             LateParsedDefaultArgument(FTI.ArgInfo[I].Param));
1217d33133cdc1af466f9c276249b2621be03867888bEli Friedman      }
1218d33133cdc1af466f9c276249b2621be03867888bEli Friedman
1219d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // Add this parameter to the list of parameters (it or may
1220d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // not have a default argument).
1221d33133cdc1af466f9c276249b2621be03867888bEli Friedman      LateMethod->DefaultArgs.push_back(
1222d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
1223d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                  FTI.ArgInfo[ParamIdx].DefaultArgTokens));
1224d33133cdc1af466f9c276249b2621be03867888bEli Friedman    }
1225d33133cdc1af466f9c276249b2621be03867888bEli Friedman  }
1226d33133cdc1af466f9c276249b2621be03867888bEli Friedman}
1227d33133cdc1af466f9c276249b2621be03867888bEli Friedman
12284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
12294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
12304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declaration:
12314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         decl-specifier-seq[opt] member-declarator-list[opt] ';'
12324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         function-definition ';'[opt]
12334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
12344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         using-declaration                                            [TODO]
1235511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration
12365aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson///         template-declaration
1237bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU]   '__extension__' member-declaration
12384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
12394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator-list:
12404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator
12414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator-list ',' member-declarator
12424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
12434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator:
12444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         declarator pure-specifier[opt]
12454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         declarator constant-initializer[opt]
12464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         identifier[opt] ':' constant-expression
12474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
1248e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl///       pure-specifier:
12494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '= 0'
12504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
12514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       constant-initializer:
12524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '=' constant-expression
12534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
125437b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregorvoid Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
1255c9068d7dd94d439cec66c421115d15303e481025John McCall                                       const ParsedTemplateInfo &TemplateInfo,
1256c9068d7dd94d439cec66c421115d15303e481025John McCall                                       ParsingDeclRAIIObject *TemplateDiags) {
125760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  // Access declarations.
125860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  if (!TemplateInfo.Kind &&
125960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) &&
12609ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall      !TryAnnotateCXXScopeToken() &&
126160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      Tok.is(tok::annot_cxxscope)) {
126260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    bool isAccessDecl = false;
126360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    if (NextToken().is(tok::identifier))
126460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      isAccessDecl = GetLookAheadToken(2).is(tok::semi);
126560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    else
126660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      isAccessDecl = NextToken().is(tok::kw_operator);
126760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
126860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    if (isAccessDecl) {
126960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // Collect the scope specifier token we annotated earlier.
127060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      CXXScopeSpec SS;
1271b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
127260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
127360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // Try to parse an unqualified-id.
127460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      UnqualifiedId Name;
1275b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), Name)) {
127660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        SkipUntil(tok::semi);
127760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        return;
127860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      }
127960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
128060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // TODO: recover from mistakenly-qualified operator declarations.
128160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      if (ExpectAndConsume(tok::semi,
128260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           diag::err_expected_semi_after,
128360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           "access declaration",
128460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           tok::semi))
128560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        return;
128660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
128723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.ActOnUsingDeclaration(getCurScope(), AS,
128860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    false, SourceLocation(),
128960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    SS, Name,
129060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    /* AttrList */ 0,
129160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    /* IsTypeName */ false,
129260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    SourceLocation());
129360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      return;
129460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    }
129560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  }
129660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
1297511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  // static_assert-declaration
1298682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  if (Tok.is(tok::kw_static_assert)) {
129937b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    // FIXME: Check for templates
130097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
130197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    ParseStaticAssertDeclaration(DeclEnd);
1302682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1303682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
13041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1305682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  if (Tok.is(tok::kw_template)) {
13061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(!TemplateInfo.TemplateParams &&
130737b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor           "Nested template improperly parsed?");
130897144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
13091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd,
13104d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                         AS);
1311682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1312682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
13135aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson
1314bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  // Handle:  member-declaration ::= '__extension__' member-declaration
1315bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  if (Tok.is(tok::kw___extension__)) {
1316bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    // __extension__ silences extension warnings in the subexpression.
1317bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
1318bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ConsumeToken();
1319c9068d7dd94d439cec66c421115d15303e481025John McCall    return ParseCXXClassMemberDeclaration(AS, TemplateInfo, TemplateDiags);
1320bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  }
13219cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
13224ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it
13234ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // is a bitfield.
1324a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner  ColonProtectionRAIIObject X(*this);
1325193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1326bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  CXX0XAttributeList AttrList;
1327bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // Optional C++0x attribute-specifier
1328a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
1329bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = ParseCXX0XAttributes();
1330334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  if (getLang().Microsoft && Tok.is(tok::l_square))
1331334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    ParseMicrosoftAttributes();
1332bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
13339cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_using)) {
133437b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    // FIXME: Check for template aliases
1335193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1336bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (AttrList.HasAttr)
1337bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      Diag(AttrList.Range.getBegin(), diag::err_attributes_not_allowed)
1338bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        << AttrList.Range;
13391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13409cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    // Eat 'using'.
13419cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SourceLocation UsingLoc = ConsumeToken();
13429cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
13439cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    if (Tok.is(tok::kw_namespace)) {
13449cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      Diag(UsingLoc, diag::err_using_namespace_in_class);
13459cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SkipUntil(tok::semi, true, true);
1346ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    } else {
13479cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SourceLocation DeclEnd;
13489cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      // Otherwise, it must be using-declaration.
1349595adc1795cc2c079ef5876100e01acd10a0504aAnders Carlsson      ParseUsingDeclaration(Declarator::MemberContext, UsingLoc, DeclEnd, AS);
13509cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    }
13519cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return;
13529cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
13539cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
13544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  SourceLocation DSStart = Tok.getLocation();
13554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // decl-specifier-seq:
13564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Parse the common declaration-specifiers piece.
1357c9068d7dd94d439cec66c421115d15303e481025John McCall  ParsingDeclSpec DS(*this, TemplateDiags);
1358bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  DS.AddAttributes(AttrList.AttrList);
135937b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor  ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class);
13604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1361f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  MultiTemplateParamsArg TemplateParams(Actions,
1362dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
1363dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
1364dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
13654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::semi)) {
13664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
1367d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decl *TheDecl =
1368c9068d7dd94d439cec66c421115d15303e481025John McCall      Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS);
1369c9068d7dd94d439cec66c421115d15303e481025John McCall    DS.complete(TheDecl);
137067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    return;
13714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
137207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
137354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext);
13744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13753a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis  if (Tok.isNot(tok::colon)) {
1376a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner    // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
1377a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner    ColonProtectionRAIIObject X(*this);
1378a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner
13793a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Parse the first declarator.
13803a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    ParseDeclarator(DeclaratorInfo);
13813a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Error parsing the declarator?
138210bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor    if (!DeclaratorInfo.hasName()) {
13833a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      // If so, skip until the semi-colon or a }.
13844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      SkipUntil(tok::r_brace, true);
13853a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (Tok.is(tok::semi))
13863a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeToken();
1387682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
13884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
13894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13901b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson    // If attributes exist after the declarator, but before an '{', parse them.
13911b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson    if (Tok.is(tok::kw___attribute)) {
13921b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson      SourceLocation Loc;
13931b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson      AttributeList *AttrList = ParseGNUAttributes(&Loc);
13941b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson      DeclaratorInfo.AddAttributes(AttrList, Loc);
13951b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson    }
13961b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson
13973a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // function-definition:
13987ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    if (Tok.is(tok::l_brace)
1399d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl        || (DeclaratorInfo.isFunctionDeclarator() &&
1400d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl            (Tok.is(tok::colon) || Tok.is(tok::kw_try)))) {
14013a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (!DeclaratorInfo.isFunctionDeclarator()) {
14023a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        Diag(Tok, diag::err_func_def_no_params);
14033a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
14043a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        SkipUntil(tok::r_brace, true);
1405682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
14063a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
14073a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis
14083a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
14093a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        Diag(Tok, diag::err_function_declared_typedef);
14103a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // This recovery skips the entire function body. It would be nice
14113a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // to simply call ParseCXXInlineMethodDef() below, however Sema
14123a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // assumes the declarator represents a function, not a typedef.
14133a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
14143a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        SkipUntil(tok::r_brace, true);
1415682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
14163a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
14174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
141837b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor      ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo);
1419682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
14203a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    }
14214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
14224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
14234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // member-declarator-list:
14244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator
14254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator-list ',' member-declarator
14264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1427d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  llvm::SmallVector<Decl *, 8> DeclsInGroup;
142860d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult BitfieldSize;
142960d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Init;
1430e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl  bool Deleted = false;
14314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
14324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  while (1) {
14334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // member-declarator:
14344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   declarator pure-specifier[opt]
14354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   declarator constant-initializer[opt]
14364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   identifier[opt] ':' constant-expression
14374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::colon)) {
14384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
14390e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      BitfieldSize = ParseConstantExpression();
14400e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      if (BitfieldSize.isInvalid())
14414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        SkipUntil(tok::comma, true, true);
14424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
14431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // pure-specifier:
14454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   '= 0'
14464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //
14474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // constant-initializer:
14484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   '=' constant-expression
1449e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //
1450e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    // defaulted/deleted function-definition:
1451e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //   '=' 'default'                          [TODO]
1452e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //   '=' 'delete'
14534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::equal)) {
14544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
145537bf9d2bb74944c9d9a52522412bc077629977f1Anders Carlsson      if (Tok.is(tok::kw_delete)) {
145637bf9d2bb74944c9d9a52522412bc077629977f1Anders Carlsson        if (!getLang().CPlusPlus0x)
145737bf9d2bb74944c9d9a52522412bc077629977f1Anders Carlsson          Diag(Tok, diag::warn_deleted_function_accepted_as_extension);
1458e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        ConsumeToken();
1459e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        Deleted = true;
1460e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl      } else {
1461e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        Init = ParseInitializer();
1462e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        if (Init.isInvalid())
1463e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl          SkipUntil(tok::comma, true, true);
1464e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl      }
14654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
14664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1467e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    // If a simple-asm-expr is present, parse it.
1468e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    if (Tok.is(tok::kw_asm)) {
1469e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      SourceLocation Loc;
147060d7b3a319d84d688752be3870615ac0f111fb16John McCall      ExprResult AsmLabel(ParseSimpleAsm(&Loc));
1471e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      if (AsmLabel.isInvalid())
1472e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner        SkipUntil(tok::comma, true, true);
1473e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner
1474e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      DeclaratorInfo.setAsmLabel(AsmLabel.release());
1475e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      DeclaratorInfo.SetRangeEnd(Loc);
1476e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    }
1477e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner
14784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If attributes exist after the declarator, parse them.
1479ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    if (Tok.is(tok::kw___attribute)) {
1480ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      SourceLocation Loc;
1481bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttributeList *AttrList = ParseGNUAttributes(&Loc);
1482ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      DeclaratorInfo.AddAttributes(AttrList, Loc);
1483ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    }
14844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
148507952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // NOTE: If Sema is the Action module and declarator is an instance field,
1486682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    // this call will *not* return the created decl; It will return null.
148707952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // See Sema::ActOnCXXMemberDeclarator for details.
148867d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall
1489d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decl *ThisDecl = 0;
149067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    if (DS.isFriendSpecified()) {
1491bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall      // TODO: handle initializers, bitfields, 'delete'
149223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo,
1493bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall                                                 /*IsDefinition*/ false,
1494bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall                                                 move(TemplateParams));
149537b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    } else {
149623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS,
149767d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  DeclaratorInfo,
149837b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor                                                  move(TemplateParams),
149967d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  BitfieldSize.release(),
150067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  Init.release(),
1501d1a7846699a82f85ff3ce6b2e383409537c3f5c5Sebastian Redl                                                  /*IsDefinition*/Deleted,
150267d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  Deleted);
150337b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    }
1504682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    if (ThisDecl)
1505682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      DeclsInGroup.push_back(ThisDecl);
15064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
150772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    if (DeclaratorInfo.isFunctionDeclarator() &&
15081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        DeclaratorInfo.getDeclSpec().getStorageClassSpec()
150972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor          != DeclSpec::SCS_typedef) {
1510d33133cdc1af466f9c276249b2621be03867888bEli Friedman      HandleMemberFunctionDefaultArgs(DeclaratorInfo, ThisDecl);
151172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    }
151272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor
151354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    DeclaratorInfo.complete(ThisDecl);
151454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
15154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If we don't have a comma, it is either the end of the list (a ';')
15164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // or an error, bail out.
15174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.isNot(tok::comma))
15184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
15191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Consume the comma.
15214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
15221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Parse the next declarator.
15244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    DeclaratorInfo.clear();
152515faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl    BitfieldSize = 0;
152615faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl    Init = 0;
1527e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    Deleted = false;
15281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Attributes are only allowed on the second declarator.
1530ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    if (Tok.is(tok::kw___attribute)) {
1531ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      SourceLocation Loc;
1532bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttributeList *AttrList = ParseGNUAttributes(&Loc);
1533ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      DeclaratorInfo.AddAttributes(AttrList, Loc);
1534ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    }
15354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
15363a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    if (Tok.isNot(tok::colon))
15373a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      ParseDeclarator(DeclaratorInfo);
15384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
15394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1540ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner  if (ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
1541ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    // Skip to end of block or statement.
1542ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    SkipUntil(tok::r_brace, true, true);
1543ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    // If we stopped at a ';', eat it.
1544ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    if (Tok.is(tok::semi)) ConsumeToken();
1545682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
15464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
15474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
154823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup.data(),
1549ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner                                  DeclsInGroup.size());
15504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
15514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
15524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition.
15534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
15544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-specification:
15554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declaration member-specification[opt]
15564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         access-specifier ':' member-specification[opt]
15574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
15584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidisvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
1559d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall                                         unsigned TagType, Decl *TagDecl) {
156031fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta  assert((TagType == DeclSpec::TST_struct ||
15614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis         TagType == DeclSpec::TST_union  ||
156231fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta         TagType == DeclSpec::TST_class) && "Invalid TagType!");
15634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1564f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
1565f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing struct/union/class body");
15661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
156726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  // Determine whether this is a non-nested class. Note that local
156826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  // classes are *not* considered to be nested classes.
156926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  bool NonNestedClass = true;
157026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  if (!ClassStack.empty()) {
157123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    for (const Scope *S = getCurScope(); S; S = S->getParent()) {
157226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      if (S->isClassScope()) {
157326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // We're inside a class scope, so this is a nested class.
157426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        NonNestedClass = false;
157526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        break;
157626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      }
157726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor
157826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      if ((S->getFlags() & Scope::FnScope)) {
157926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // If we're in a function or function template declared in the
158026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // body of a class, then this is a local class rather than a
158126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // nested class.
158226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        const Scope *Parent = S->getParent();
158326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        if (Parent->isTemplateParamScope())
158426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor          Parent = Parent->getParent();
158526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        if (Parent->isClassScope())
158626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor          break;
158726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      }
158826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor    }
158926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  }
15904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
15914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Enter a scope for the class.
15923218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
15934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
15946569d68745c8213709740337d2be52b031384f58Douglas Gregor  // Note that we are parsing a new (potentially-nested) class definition.
159526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass);
15966569d68745c8213709740337d2be52b031384f58Douglas Gregor
1597ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  if (TagDecl)
159823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
1599bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
1600bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  if (Tok.is(tok::colon)) {
1601bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    ParseBaseClause(TagDecl);
1602bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
1603bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    if (!Tok.is(tok::l_brace)) {
1604bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall      Diag(Tok, diag::err_expected_lbrace_after_base_specifiers);
1605db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall
1606db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall      if (TagDecl)
160723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);
1608bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall      return;
1609bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    }
1610bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  }
1611bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
1612bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  assert(Tok.is(tok::l_brace));
1613bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
1614bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  SourceLocation LBraceLoc = ConsumeBrace();
1615bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
161642a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
161723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, LBraceLoc);
1618f9368159334ff86ea5fa367225c1a580977f3b03John McCall
16194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // C++ 11p3: Members of a class defined with the keyword class are private
16204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // by default. Members of a class defined with the keywords struct or union
16214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // are public by default.
16224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  AccessSpecifier CurAS;
16234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (TagType == DeclSpec::TST_class)
16244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_private;
16254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  else
16264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_public;
16274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
162807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  SourceLocation RBraceLoc;
162907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  if (TagDecl) {
163007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    // While we still have something to read, read the member-declarations.
163107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
163207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Each iteration of this loop reads one member-declaration.
163307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor
163407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Check for extraneous top-level semicolon.
163507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      if (Tok.is(tok::semi)) {
163607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        Diag(Tok, diag::ext_extra_struct_semi)
163707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor          << DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
163807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor          << FixItHint::CreateRemoval(Tok.getLocation());
163907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        ConsumeToken();
164007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        continue;
164107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      }
16421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
164307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      AccessSpecifier AS = getAccessSpecifierIfPresent();
164407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      if (AS != AS_none) {
164507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        // Current token is a C++ access specifier.
164607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        CurAS = AS;
164707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        SourceLocation ASLoc = Tok.getLocation();
164807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        ConsumeToken();
164907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        if (Tok.is(tok::colon))
165007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor          Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
165107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        else
165207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor          Diag(Tok, diag::err_expected_colon);
165307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        ConsumeToken();
165407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        continue;
165507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      }
16564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
165707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // FIXME: Make sure we don't have a template here.
16584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
165907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Parse all the comma separated declarators.
166007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      ParseCXXClassMemberDeclaration(CurAS);
166107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    }
16621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
166307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
166407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  } else {
166507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    SkipUntil(tok::r_brace, false, false);
16664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
16671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // If attributes exist after class contents, parse them.
16691e37765c9257ef1d051f54a674eaa964bdba9693Ted Kremenek  llvm::OwningPtr<AttributeList> AttrList;
16704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::kw___attribute))
16710b4c9b5834a0a5520d2cd32227a53cf7f73fedcaDouglas Gregor    AttrList.reset(ParseGNUAttributes());
16724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
167342a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
167423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
167542a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall                                              LBraceLoc, RBraceLoc,
167642a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall                                              AttrList.get());
16774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
16784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // C++ 9.2p2: Within the class member-specification, the class is regarded as
16794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // complete within function bodies, default arguments,
16804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // exception-specifications, and constructor ctor-initializers (including
16814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // such things in nested classes).
16824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //
168372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor  // FIXME: Only function bodies and constructor ctor-initializers are
168472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor  // parsed correctly, fix the rest.
168507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  if (TagDecl && NonNestedClass) {
16864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // We are not inside a nested class. This class and its nested classes
168772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    // are complete and we can parse the delayed portions of method
168872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    // declarations and the lexed inline method definitions.
1689e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor    SourceLocation SavedPrevTokLocation = PrevTokLocation;
16906569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDeclarations(getCurrentClass());
16916569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDefs(getCurrentClass());
1692e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor    PrevTokLocation = SavedPrevTokLocation;
16934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
16944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
169542a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
169623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, RBraceLoc);
1697db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall
16984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Leave the class scope.
16996569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingDef.Pop();
17008935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ClassScope.Exit();
17014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
17027ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
17037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer,
17047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a
17057ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers
17067ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below:
17077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
17087ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code
17097ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { };
17107ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base {
17117ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   int x;
17127ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   float f;
17137ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public:
17147ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   Derived(float f) : Base(), x(17), f(f) { }
17157ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// };
17167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode
17177ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
17181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  ctor-initializer:
17191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///          ':' mem-initializer-list
17207ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
17211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  mem-initializer-list:
17221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///          mem-initializer
17231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///          mem-initializer , mem-initializer-list
1724d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
17257ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
17267ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
17277ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation ColonLoc = ConsumeToken();
17281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1729ca0408fb49c1370430672acf2d770b7151cf71deJohn McCall  llvm::SmallVector<CXXBaseOrMemberInitializer*, 4> MemInitializers;
17309db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  bool AnyErrors = false;
1731193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
17327ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  do {
17330133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    if (Tok.is(tok::code_completion)) {
17340133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      Actions.CodeCompleteConstructorInitializer(ConstructorDecl,
17350133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor                                                 MemInitializers.data(),
17360133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor                                                 MemInitializers.size());
17370133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      ConsumeCodeCompletionToken();
17380133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    } else {
17390133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
17400133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      if (!MemInit.isInvalid())
17410133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor        MemInitializers.push_back(MemInit.get());
17420133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      else
17430133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor        AnyErrors = true;
17440133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    }
17450133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor
17467ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    if (Tok.is(tok::comma))
17477ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      ConsumeToken();
17487ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    else if (Tok.is(tok::l_brace))
17497ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
1750b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor    // If the next token looks like a base or member initializer, assume that
1751b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor    // we're just missing a comma.
1752751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor    else if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) {
1753751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor      SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
1754751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor      Diag(Loc, diag::err_ctor_init_missing_comma)
1755751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor        << FixItHint::CreateInsertion(Loc, ", ");
1756751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor    } else {
17577ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      // Skip over garbage, until we get to '{'.  Don't eat the '{'.
1758d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl      Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
17597ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      SkipUntil(tok::l_brace, true, true);
17607ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
17617ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    }
17627ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  } while (true);
17637ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
17641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc,
17659db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                               MemInitializers.data(), MemInitializers.size(),
17669db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                               AnyErrors);
17677ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
17687ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
17697ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is
17707ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one
17717ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See
17727ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example.
17737ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
17747ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer:
17757ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         mem-initializer-id '(' expression-list[opt] ')'
17761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
17777ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id:
17787ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         '::'[opt] nested-name-specifier[opt] class-name
17797ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         identifier
1780d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
1781bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  // parse '::'[opt] nested-name-specifier[opt]
1782bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  CXXScopeSpec SS;
1783b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
1784b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TemplateTypeTy;
1785961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (Tok.is(tok::annot_template_id)) {
1786961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    TemplateIdAnnotation *TemplateId
1787961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
1788d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor    if (TemplateId->Kind == TNK_Type_template ||
1789d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor        TemplateId->Kind == TNK_Dependent_template_name) {
1790961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      AnnotateTemplateIdTokenAsType(&SS);
1791961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
1792b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      TemplateTypeTy = getTypeAnnotation(Tok);
1793961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    }
1794961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  }
1795961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (!TemplateTypeTy && Tok.isNot(tok::identifier)) {
17961ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_member_or_base_name);
17977ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
17987ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
17991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18007ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Get the identifier. This may be a member name or a class name,
18017ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // but we'll let the semantic analysis determine which it is.
1802961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  IdentifierInfo *II = Tok.is(tok::identifier) ? Tok.getIdentifierInfo() : 0;
18037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation IdLoc = ConsumeToken();
18047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
18057ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Parse the '('.
18067ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  if (Tok.isNot(tok::l_paren)) {
18071ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen);
18087ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
18097ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
18107ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation LParenLoc = ConsumeParen();
18117ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
18127ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Parse the optional expression-list.
1813a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl  ExprVector ArgExprs(Actions);
18147ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  CommaLocsTy CommaLocs;
18157ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
18167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    SkipUntil(tok::r_paren);
18177ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
18187ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
18197ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
18207ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
18217ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
182223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
1823961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian                                     TemplateTypeTy, IdLoc,
1824a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl                                     LParenLoc, ArgExprs.take(),
1825a1a04786cea2445759026edacd096abd1fbf4a05Douglas Gregor                                     ArgExprs.size(), RParenLoc);
18267ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
18270fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
18280fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// ParseExceptionSpecification - Parse a C++ exception-specification
18290fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// (C++ [except.spec]).
18300fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
1831a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       exception-specification:
1832a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         'throw' '(' type-id-list [opt] ')'
1833a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS]    'throw' '(' '...' ')'
18341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
1835a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       type-id-list:
1836a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         type-id
1837a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         type-id-list ',' type-id
18380fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
18397dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redlbool Parser::ParseExceptionSpecification(SourceLocation &EndLoc,
1840b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                         llvm::SmallVectorImpl<ParsedType>
1841ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl                                             &Exceptions,
1842b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                         llvm::SmallVectorImpl<SourceRange>
1843ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl                                             &Ranges,
18447dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl                                         bool &hasAnyExceptionSpec) {
18450fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  assert(Tok.is(tok::kw_throw) && "expected throw");
18461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18470fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  SourceLocation ThrowLoc = ConsumeToken();
18481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18490fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  if (!Tok.is(tok::l_paren)) {
18500fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor    return Diag(Tok, diag::err_expected_lparen_after) << "throw";
18510fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
18520fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  SourceLocation LParenLoc = ConsumeParen();
18530fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
1854a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // Parse throw(...), a Microsoft extension that means "this function
1855a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // can throw anything".
1856a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  if (Tok.is(tok::ellipsis)) {
18577dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl    hasAnyExceptionSpec = true;
1858a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    SourceLocation EllipsisLoc = ConsumeToken();
1859a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    if (!getLang().Microsoft)
1860a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor      Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
1861ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1862a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    return false;
1863a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  }
1864a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor
18650fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  // Parse the sequence of type-ids.
1866ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl  SourceRange Range;
18670fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  while (Tok.isNot(tok::r_paren)) {
1868ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    TypeResult Res(ParseTypeName(&Range));
1869ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    if (!Res.isInvalid()) {
18707dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl      Exceptions.push_back(Res.get());
1871ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl      Ranges.push_back(Range);
1872ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    }
18730fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor    if (Tok.is(tok::comma))
18740fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      ConsumeToken();
18757dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl    else
18760fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      break;
18770fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
18780fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
1879ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl  EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
18800fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  return false;
18810fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor}
18826569d68745c8213709740337d2be52b031384f58Douglas Gregor
1883dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// ParseTrailingReturnType - Parse a trailing return type on a new-style
1884dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// function declaration.
1885dab60ad68a3a98d687305941a3852e793705f945Douglas GregorTypeResult Parser::ParseTrailingReturnType() {
1886dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  assert(Tok.is(tok::arrow) && "expected arrow");
1887dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
1888dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  ConsumeToken();
1889dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
1890dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  // FIXME: Need to suppress declarations when parsing this typename.
1891dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  // Otherwise in this function definition:
1892dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  //
1893dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  //   auto f() -> struct X {}
1894dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  //
1895dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  // struct X is parsed as class definition because of the trailing
1896dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  // brace.
1897dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
1898dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  SourceRange Range;
1899dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  return ParseTypeName(&Range);
1900dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor}
1901dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
19026569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief We have just started parsing the definition of a new class,
19036569d68745c8213709740337d2be52b031384f58Douglas Gregor/// so push that class onto our stack of classes that is currently
19046569d68745c8213709740337d2be52b031384f58Douglas Gregor/// being parsed.
1905d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass) {
190626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  assert((NonNestedClass || !ClassStack.empty()) &&
19076569d68745c8213709740337d2be52b031384f58Douglas Gregor         "Nested class without outer class");
190826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass));
19096569d68745c8213709740337d2be52b031384f58Douglas Gregor}
19106569d68745c8213709740337d2be52b031384f58Douglas Gregor
19116569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Deallocate the given parsed class and all of its nested
19126569d68745c8213709740337d2be52b031384f58Douglas Gregor/// classes.
19136569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
19146569d68745c8213709740337d2be52b031384f58Douglas Gregor  for (unsigned I = 0, N = Class->NestedClasses.size(); I != N; ++I)
19156569d68745c8213709740337d2be52b031384f58Douglas Gregor    DeallocateParsedClasses(Class->NestedClasses[I]);
19166569d68745c8213709740337d2be52b031384f58Douglas Gregor  delete Class;
19176569d68745c8213709740337d2be52b031384f58Douglas Gregor}
19186569d68745c8213709740337d2be52b031384f58Douglas Gregor
19196569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Pop the top class of the stack of classes that are
19206569d68745c8213709740337d2be52b031384f58Douglas Gregor/// currently being parsed.
19216569d68745c8213709740337d2be52b031384f58Douglas Gregor///
19226569d68745c8213709740337d2be52b031384f58Douglas Gregor/// This routine should be called when we have finished parsing the
19236569d68745c8213709740337d2be52b031384f58Douglas Gregor/// definition of a class, but have not yet popped the Scope
19246569d68745c8213709740337d2be52b031384f58Douglas Gregor/// associated with the class's definition.
19256569d68745c8213709740337d2be52b031384f58Douglas Gregor///
19266569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \returns true if the class we've popped is a top-level class,
19276569d68745c8213709740337d2be52b031384f58Douglas Gregor/// false otherwise.
19286569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::PopParsingClass() {
19296569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");
19301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19316569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingClass *Victim = ClassStack.top();
19326569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.pop();
19336569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (Victim->TopLevelClass) {
19346569d68745c8213709740337d2be52b031384f58Douglas Gregor    // Deallocate all of the nested classes of this class,
19356569d68745c8213709740337d2be52b031384f58Douglas Gregor    // recursively: we don't need to keep any of this information.
19366569d68745c8213709740337d2be52b031384f58Douglas Gregor    DeallocateParsedClasses(Victim);
19376569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
19381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
19396569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Missing top-level class?");
19406569d68745c8213709740337d2be52b031384f58Douglas Gregor
19416569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (Victim->MethodDecls.empty() && Victim->MethodDefs.empty() &&
19426569d68745c8213709740337d2be52b031384f58Douglas Gregor      Victim->NestedClasses.empty()) {
19436569d68745c8213709740337d2be52b031384f58Douglas Gregor    // The victim is a nested class, but we will not need to perform
19446569d68745c8213709740337d2be52b031384f58Douglas Gregor    // any processing after the definition of this class since it has
19456569d68745c8213709740337d2be52b031384f58Douglas Gregor    // no members whose handling was delayed. Therefore, we can just
19466569d68745c8213709740337d2be52b031384f58Douglas Gregor    // remove this nested class.
19476569d68745c8213709740337d2be52b031384f58Douglas Gregor    delete Victim;
19486569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
19496569d68745c8213709740337d2be52b031384f58Douglas Gregor  }
19506569d68745c8213709740337d2be52b031384f58Douglas Gregor
19516569d68745c8213709740337d2be52b031384f58Douglas Gregor  // This nested class has some members that will need to be processed
19526569d68745c8213709740337d2be52b031384f58Douglas Gregor  // after the top-level class is completely defined. Therefore, add
19536569d68745c8213709740337d2be52b031384f58Douglas Gregor  // it to the list of nested classes within its parent.
195423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  assert(getCurScope()->isClassScope() && "Nested class outside of class scope?");
19556569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.top()->NestedClasses.push_back(Victim);
195623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope();
19576569d68745c8213709740337d2be52b031384f58Douglas Gregor}
1958bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1959bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// ParseCXX0XAttributes - Parse a C++0x attribute-specifier. Currently only
1960bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// parses standard attributes.
1961bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1962bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-specifier:
1963bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' '[' attribute-list ']' ']'
1964bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1965bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-list:
1966bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute[opt]
1967bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-list ',' attribute[opt]
1968bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1969bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute:
1970bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-token attribute-argument-clause[opt]
1971bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1972bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-token:
1973bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
1974bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-scoped-token
1975bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1976bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-scoped-token:
1977bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-namespace '::' identifier
1978bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1979bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-namespace:
1980bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
1981bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1982bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-argument-clause:
1983bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
1984bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1985bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] balanced-token-seq:
1986bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token
1987bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token-seq balanced-token
1988bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1989bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] balanced-token:
1990bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
1991bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' balanced-token-seq ']'
1992bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '{' balanced-token-seq '}'
1993bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         any token but '(', ')', '[', ']', '{', or '}'
1994bbd37c62e34db3f5a95c899723484a76c71d7757Sean HuntCXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
1995bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
1996bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      && "Not a C++0x attribute list");
1997bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1998bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  SourceLocation StartLoc = Tok.getLocation(), Loc;
1999bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  AttributeList *CurrAttr = 0;
2000bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2001bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
2002bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
2003193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
2004bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Tok.is(tok::comma)) {
2005bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Diag(Tok.getLocation(), diag::err_expected_ident);
2006bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    ConsumeToken();
2007bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
2008bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2009bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  while (Tok.is(tok::identifier) || Tok.is(tok::comma)) {
2010bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // attribute not present
2011bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::comma)) {
2012bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
2013bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      continue;
2014bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2015bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2016bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    IdentifierInfo *ScopeName = 0, *AttrName = Tok.getIdentifierInfo();
2017bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceLocation ScopeLoc, AttrLoc = ConsumeToken();
2018193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
2019bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // scoped attribute
2020bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::coloncolon)) {
2021bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
2022bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2023bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      if (!Tok.is(tok::identifier)) {
2024bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        Diag(Tok.getLocation(), diag::err_expected_ident);
2025bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        SkipUntil(tok::r_square, tok::comma, true, true);
2026bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        continue;
2027bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2028193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
2029bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ScopeName = AttrName;
2030bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ScopeLoc = AttrLoc;
2031bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2032bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttrName = Tok.getIdentifierInfo();
2033bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttrLoc = ConsumeToken();
2034bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2035bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2036bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    bool AttrParsed = false;
2037bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // No scoped names are supported; ideally we could put all non-standard
2038bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // attributes into namespaces.
2039bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (!ScopeName) {
2040bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      switch(AttributeList::getKind(AttrName))
2041bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      {
2042bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // No arguments
20437725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_base_check:
20447725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_carries_dependency:
2045bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      case AttributeList::AT_final:
20467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_hiding:
20477725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_noreturn:
20487725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_override: {
2049bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        if (Tok.is(tok::l_paren)) {
2050bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          Diag(Tok.getLocation(), diag::err_cxx0x_attribute_forbids_arguments)
2051bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt            << AttrName->getName();
2052bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          break;
2053bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        }
2054bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2055bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        CurrAttr = new AttributeList(AttrName, AttrLoc, 0, AttrLoc, 0,
2056bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                     SourceLocation(), 0, 0, CurrAttr, false,
2057bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                     true);
2058bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        AttrParsed = true;
2059bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        break;
2060bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2061bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2062bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // One argument; must be a type-id or assignment-expression
2063bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      case AttributeList::AT_aligned: {
2064bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        if (Tok.isNot(tok::l_paren)) {
2065bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          Diag(Tok.getLocation(), diag::err_cxx0x_attribute_requires_arguments)
2066bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt            << AttrName->getName();
2067bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          break;
2068bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        }
2069bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        SourceLocation ParamLoc = ConsumeParen();
2070bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
207160d7b3a319d84d688752be3870615ac0f111fb16John McCall        ExprResult ArgExpr = ParseCXX0XAlignArgument(ParamLoc);
2072bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2073bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        MatchRHSPunctuation(tok::r_paren, ParamLoc);
2074bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2075bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        ExprVector ArgExprs(Actions);
2076bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        ArgExprs.push_back(ArgExpr.release());
2077bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        CurrAttr = new AttributeList(AttrName, AttrLoc, 0, AttrLoc,
2078bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                     0, ParamLoc, ArgExprs.take(), 1, CurrAttr,
2079bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                     false, true);
2080bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2081bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        AttrParsed = true;
2082bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        break;
2083bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2084bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2085bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // Silence warnings
2086bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      default: break;
2087bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2088bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2089bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2090bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // Skip the entire parameter clause, if any
2091bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (!AttrParsed && Tok.is(tok::l_paren)) {
2092bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeParen();
2093bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // SkipUntil maintains the balancedness of tokens.
2094bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      SkipUntil(tok::r_paren, false);
2095bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2096bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
2097bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2098bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
2099bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
2100bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  Loc = Tok.getLocation();
2101bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
2102bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
2103bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2104bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  CXX0XAttributeList Attr (CurrAttr, SourceRange(StartLoc, Loc), true);
2105bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  return Attr;
2106bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
2107bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2108bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// ParseCXX0XAlignArgument - Parse the argument to C++0x's [[align]]
2109bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute.
2110bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2111bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// FIXME: Simply returns an alignof() expression if the argument is a
2112bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// type. Ideally, the type should be propagated directly into Sema.
2113bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2114bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] 'align' '(' type-id ')'
2115bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] 'align' '(' assignment-expression ')'
211660d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) {
2117bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (isTypeIdInParens()) {
2118f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
2119bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceLocation TypeLoc = Tok.getLocation();
2120b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    ParsedType Ty = ParseTypeName().get();
2121bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceRange TypeRange(Start, Tok.getLocation());
2122b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    return Actions.ActOnSizeOfAlignOfExpr(TypeLoc, false, true,
2123b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                          Ty.getAsOpaquePtr(), TypeRange);
2124bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  } else
2125bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return ParseConstantExpression();
2126bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
2127334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet
2128334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ParseMicrosoftAttributes - Parse a Microsoft attribute [Attr]
2129334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///
2130334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute:
2131334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             '[' token-seq ']'
2132334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///
2133334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute-seq:
2134334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             ms-attribute[opt]
2135334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             ms-attribute ms-attribute-seq
2136334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichetvoid Parser::ParseMicrosoftAttributes() {
2137334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
2138334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet
2139334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  while (Tok.is(tok::l_square)) {
2140334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    ConsumeBracket();
2141334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    SkipUntil(tok::r_square, true, true);
2142334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
2143334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  }
2144334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet}
2145