ParseDeclCXX.cpp revision e761230ae3751b525cadd8066c74ec278ee4ef57
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'.
559735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian  ObjCDeclContextSwitch ObjCDC(*this);
56a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian
5749f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
5823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteNamespaceDecl(getCurScope());
597d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
607d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
6149f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
62193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
638f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation IdentLoc;
648f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  IdentifierInfo *Ident = 0;
65f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  std::vector<SourceLocation> ExtraIdentLoc;
66f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  std::vector<IdentifierInfo*> ExtraIdent;
67f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  std::vector<SourceLocation> ExtraNamespaceLoc;
686a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
696a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  Token attrTok;
701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7104d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  if (Tok.is(tok::identifier)) {
728f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    Ident = Tok.getIdentifierInfo();
738f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    IdentLoc = ConsumeToken();  // eat the identifier.
74f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    while (Tok.is(tok::coloncolon) && NextToken().is(tok::identifier)) {
75f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ExtraNamespaceLoc.push_back(ConsumeToken());
76f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ExtraIdent.push_back(Tok.getIdentifierInfo());
77f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ExtraIdentLoc.push_back(ConsumeToken());
78f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
798f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  }
801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
818f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  // Read label attributes, if present.
820b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
836a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::kw___attribute)) {
846a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor    attrTok = Tok;
857f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
866a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
886a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::equal)) {
897f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    if (!attrs.empty())
906a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor      Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
91d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl    if (InlineLoc.isValid())
92d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl      Diag(InlineLoc, diag::err_inline_namespace_alias)
93d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl          << FixItHint::CreateRemoval(InlineLoc);
949735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian    return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
956a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
97f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
985144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  if (Tok.isNot(tok::l_brace)) {
99f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    if (!ExtraIdent.empty()) {
100f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
101f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back());
102f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Diag(Tok, Ident ? diag::err_expected_lbrace :
1045144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner         diag::err_expected_ident_lbrace);
105d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
1065144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  }
1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1085144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  SourceLocation LBrace = ConsumeBrace();
1092d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
11023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() ||
11123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      getCurScope()->isInObjcMethodScope() || getCurScope()->getBlockParent() ||
11223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      getCurScope()->getFnParent()) {
113f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    if (!ExtraIdent.empty()) {
114f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
115f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back());
116f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
11795f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor    Diag(LBrace, diag::err_namespace_nonnamespace_scope);
11895f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor    SkipUntil(tok::r_brace, false);
119d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
12095f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor  }
12195f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor
122f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  if (!ExtraIdent.empty()) {
123f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    TentativeParsingAction TPA(*this);
124f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    SkipUntil(tok::r_brace, /*StopAtSemi*/false, /*DontConsume*/true);
125f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    Token rBraceToken = Tok;
126f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    TPA.Revert();
127f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
128f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    if (!rBraceToken.is(tok::r_brace)) {
129f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
130f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back());
131f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    } else {
1329910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer      std::string NamespaceFix;
133f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      for (std::vector<IdentifierInfo*>::iterator I = ExtraIdent.begin(),
134f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu           E = ExtraIdent.end(); I != E; ++I) {
135f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu        NamespaceFix += " { namespace ";
136f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu        NamespaceFix += (*I)->getName();
137f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      }
1389910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer
139f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      std::string RBraces;
1409910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer      for (unsigned i = 0, e = ExtraIdent.size(); i != e; ++i)
141f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu        RBraces +=  "} ";
1429910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer
143f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
144f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << FixItHint::CreateReplacement(SourceRange(ExtraNamespaceLoc.front(),
145f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                                      ExtraIdentLoc.back()),
146f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                          NamespaceFix)
147f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << FixItHint::CreateInsertion(rBraceToken.getLocation(), RBraces);
148f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
149f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  }
150f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
15188e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl  // If we're still good, complain about inline namespaces in non-C++0x now.
15288e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl  if (!getLang().CPlusPlus0x && InlineLoc.isValid())
15388e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl    Diag(InlineLoc, diag::ext_inline_namespace);
15488e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl
1555144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Enter a scope for the namespace.
1565144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  ParseScope NamespaceScope(this, Scope::DeclScope);
1572d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
158d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *NamespcDecl =
159acba90f30876b4140b738f0d3dd0e50724053a96Abramo Bagnara    Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, NamespaceLoc,
160acba90f30876b4140b738f0d3dd0e50724053a96Abramo Bagnara                                   IdentLoc, Ident, LBrace, attrs.getList());
1612d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
162f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc,
163f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing namespace");
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
165f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  SourceLocation RBraceLoc;
166f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  // Parse the contents of the namespace.  This includes parsing recovery on
167f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  // any improperly nested namespaces.
168f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  ParseInnerNamespace(ExtraIdentLoc, ExtraIdent, ExtraNamespaceLoc, 0,
169f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                      InlineLoc, LBrace, attrs, RBraceLoc);
1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1715144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Leave the namespace scope.
1725144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  NamespaceScope.Exit();
1738ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis
17497144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  Actions.ActOnFinishNamespaceDef(NamespcDecl, RBraceLoc);
1752d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
17697144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = RBraceLoc;
1775144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  return NamespcDecl;
1788f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner}
179c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
180f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu/// ParseInnerNamespace - Parse the contents of a namespace.
181f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieuvoid Parser::ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc,
182f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 std::vector<IdentifierInfo*>& Ident,
183f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 std::vector<SourceLocation>& NamespaceLoc,
184f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 unsigned int index, SourceLocation& InlineLoc,
185f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 SourceLocation& LBrace,
186f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 ParsedAttributes& attrs,
187f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 SourceLocation& RBraceLoc) {
188f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  if (index == Ident.size()) {
189f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
190f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ParsedAttributesWithRange attrs(AttrFactory);
191f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      MaybeParseCXX0XAttributes(attrs);
192f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      MaybeParseMicrosoftAttributes(attrs);
193f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ParseExternalDeclaration(attrs);
194f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
195f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBrace);
196f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
197f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    return;
198f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  }
199f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
200f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  // Parse improperly nested namespaces.
201f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  ParseScope NamespaceScope(this, Scope::DeclScope);
202f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  Decl *NamespcDecl =
203f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    Actions.ActOnStartNamespaceDef(getCurScope(), SourceLocation(),
204f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                   NamespaceLoc[index], IdentLoc[index],
205f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                   Ident[index], LBrace, attrs.getList());
206f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
207f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  ParseInnerNamespace(IdentLoc, Ident, NamespaceLoc, ++index, InlineLoc,
208f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                      LBrace, attrs, RBraceLoc);
209f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
210f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  NamespaceScope.Exit();
211f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
212f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  Actions.ActOnFinishNamespaceDef(NamespcDecl, RBraceLoc);
213f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu}
214f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
215f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
216f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// alias definition.
217f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson///
218d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
2190b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  SourceLocation AliasLoc,
2200b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  IdentifierInfo *Alias,
2210b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  SourceLocation &DeclEnd) {
222f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  assert(Tok.is(tok::equal) && "Not equal token");
2231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
224f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  ConsumeToken(); // eat the '='.
2251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22649f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
22723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteNamespaceAliasDecl(getCurScope());
2287d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
2297d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
23049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
231193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
232f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  CXXScopeSpec SS;
233f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse (optional) nested-name-specifier.
234b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
235f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
236f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
237f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    Diag(Tok, diag::err_expected_namespace_name);
238f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    // Skip to end of the definition and eat the ';'.
239f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    SkipUntil(tok::semi);
240d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
241f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  }
242f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
243f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse identifier.
24403bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  IdentifierInfo *Ident = Tok.getIdentifierInfo();
24503bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  SourceLocation IdentLoc = ConsumeToken();
2461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
247f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Eat the ';'.
24897144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
2496869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name,
2506869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner                   "", tok::semi);
2511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
25223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc, Alias,
25303bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson                                        SS, IdentLoc, Ident);
254f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson}
255f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
256c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal
257c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen.
258c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
259c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///       linkage-specification: [C++ 7.5p2: dcl.link]
260c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal '{' declaration-seq[opt] '}'
261c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal declaration
262c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
2637d64271b162eaf5cae264ff64465b28af623dc17Chris LattnerDecl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
264c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor  assert(Tok.is(tok::string_literal) && "Not a string literal!");
265193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  llvm::SmallString<8> LangBuffer;
266453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  bool Invalid = false;
2675f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid);
268453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  if (Invalid)
269d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
270c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
271c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  SourceLocation Loc = ConsumeStringToken();
272c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
273074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  ParseScope LinkageScope(this, Scope::DeclScope);
274d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *LinkageSpec
27523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    = Actions.ActOnStartLinkageSpecification(getCurScope(),
276a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                             DS.getSourceRange().getBegin(),
277d56638180014e60538cd666cd11fde6d4698e051Benjamin Kramer                                             Loc, Lang,
278a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                      Tok.is(tok::l_brace) ? Tok.getLocation()
279074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                           : SourceLocation());
280074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
2810b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributesWithRange attrs(AttrFactory);
2827f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseCXX0XAttributes(attrs);
2837f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseMicrosoftAttributes(attrs);
284193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
285074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (Tok.isNot(tok::l_brace)) {
286f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // Reset the source range in DS, as the leading "extern"
287f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // does not really belong to the inner declaration ...
288f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    DS.SetRangeStart(SourceLocation());
289f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    DS.SetRangeEnd(SourceLocation());
290f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // ... but anyway remember that such an "extern" was seen.
29135f9a196ef897b9559de25aaecd957208f0b4f59Abramo Bagnara    DS.setExternInLinkageSpec(true);
2927f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseExternalDeclaration(attrs, &DS);
29323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
294074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                   SourceLocation());
2951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
296f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor
29763a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor  DS.abort();
29863a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor
2997f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  ProhibitAttributes(attrs);
300bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
301f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  SourceLocation LBrace = ConsumeBrace();
302f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
3030b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    ParsedAttributesWithRange attrs(AttrFactory);
3047f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseCXX0XAttributes(attrs);
3057f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseMicrosoftAttributes(attrs);
3067f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseExternalDeclaration(attrs);
307f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  }
308c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
309f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
3107d64271b162eaf5cae264ff64465b28af623dc17Chris Lattner  return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
3117d64271b162eaf5cae264ff64465b28af623dc17Chris Lattner                                                 RBrace);
312c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner}
313e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
314f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
315f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'.
316d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
31778b810559d89e996e00684335407443936ce34a1John McCall                                         const ParsedTemplateInfo &TemplateInfo,
31878b810559d89e996e00684335407443936ce34a1John McCall                                               SourceLocation &DeclEnd,
319c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                             ParsedAttributesWithRange &attrs,
320c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                               Decl **OwnedType) {
321f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_using) && "Not using token");
3229735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian  ObjCDeclContextSwitch ObjCDC(*this);
3239735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian
324f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'using'.
325f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation UsingLoc = ConsumeToken();
326f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
32749f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
32823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteUsing(getCurScope());
3297d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
3307d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
33149f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
332193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
33378b810559d89e996e00684335407443936ce34a1John McCall  // 'using namespace' means this is a using-directive.
33478b810559d89e996e00684335407443936ce34a1John McCall  if (Tok.is(tok::kw_namespace)) {
33578b810559d89e996e00684335407443936ce34a1John McCall    // Template parameters are always an error here.
33678b810559d89e996e00684335407443936ce34a1John McCall    if (TemplateInfo.Kind) {
33778b810559d89e996e00684335407443936ce34a1John McCall      SourceRange R = TemplateInfo.getSourceRange();
33878b810559d89e996e00684335407443936ce34a1John McCall      Diag(UsingLoc, diag::err_templated_using_directive)
33978b810559d89e996e00684335407443936ce34a1John McCall        << R << FixItHint::CreateRemoval(R);
34078b810559d89e996e00684335407443936ce34a1John McCall    }
34178b810559d89e996e00684335407443936ce34a1John McCall
3429735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian    return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
34378b810559d89e996e00684335407443936ce34a1John McCall  }
344bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
345162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  // Otherwise, it must be a using-declaration or an alias-declaration.
34678b810559d89e996e00684335407443936ce34a1John McCall
34778b810559d89e996e00684335407443936ce34a1John McCall  // Using declarations can't have attributes.
3487f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  ProhibitAttributes(attrs);
3492f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner
3509735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian  return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd,
351a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian                                    AS_none, OwnedType);
352f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
353f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
354f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes
355f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed.
356f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
357f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       using-directive: [C++ 7.3.p4: namespace.udir]
358f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
359f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name ;
360f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive:
361f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
362f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name attributes[opt] ;
363f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
364d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirective(unsigned Context,
36578b810559d89e996e00684335407443936ce34a1John McCall                                  SourceLocation UsingLoc,
36678b810559d89e996e00684335407443936ce34a1John McCall                                  SourceLocation &DeclEnd,
3677f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                  ParsedAttributes &attrs) {
368f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
369f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
370f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'namespace'.
371f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation NamespcLoc = ConsumeToken();
372f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
37349f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
37423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteUsingDirective(getCurScope());
3757d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
3767d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
37749f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
378193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
379f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  CXXScopeSpec SS;
380f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse (optional) nested-name-specifier.
381b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
382f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
383f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  IdentifierInfo *NamespcName = 0;
384f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation IdentLoc = SourceLocation();
385f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
386f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse namespace-name.
387823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
388f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    Diag(Tok, diag::err_expected_namespace_name);
389f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // If there was invalid namespace name, skip to end of decl, and eat ';'.
390f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    SkipUntil(tok::semi);
391f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
392d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
393f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  }
3941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
395823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse identifier.
396823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  NamespcName = Tok.getIdentifierInfo();
397823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  IdentLoc = ConsumeToken();
3981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
399823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse (optional) attributes (most likely GNU strong-using extension).
400bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  bool GNUAttr = false;
401bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Tok.is(tok::kw___attribute)) {
402bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    GNUAttr = true;
4037f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
404bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
4051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
406823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Eat ';'.
40797144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
4086869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi,
4099ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                   GNUAttr ? diag::err_expected_semi_after_attribute_list
4109ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                           : diag::err_expected_semi_after_namespace_name,
4119ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                   "", tok::semi);
412f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
41323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
4147f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                     IdentLoc, NamespcName, attrs.getList());
415f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
416f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
417162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration.
418162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// Assumes that 'using' was already seen.
419f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
420f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///     using-declaration: [C++ 7.3.p3: namespace.udecl]
421f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       'using' 'typename'[opt] ::[opt] nested-name-specifier
4229cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///               unqualified-id
4239cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///       'using' :: unqualified-id
424f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
425162e1c1b487352434552147967c3dd296ebee2f7Richard Smith///     alias-declaration: C++0x [decl.typedef]p2
426162e1c1b487352434552147967c3dd296ebee2f7Richard Smith///       'using' identifier = type-id ;
427162e1c1b487352434552147967c3dd296ebee2f7Richard Smith///
428d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDeclaration(unsigned Context,
42978b810559d89e996e00684335407443936ce34a1John McCall                                    const ParsedTemplateInfo &TemplateInfo,
43078b810559d89e996e00684335407443936ce34a1John McCall                                    SourceLocation UsingLoc,
43178b810559d89e996e00684335407443936ce34a1John McCall                                    SourceLocation &DeclEnd,
432c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                    AccessSpecifier AS,
433c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                    Decl **OwnedType) {
4349cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  CXXScopeSpec SS;
4357ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall  SourceLocation TypenameLoc;
4369cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  bool IsTypeName;
4379cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
4389cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Ignore optional 'typename'.
43912c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // FIXME: This is wrong; we should parse this as a typename-specifier.
4409cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_typename)) {
4417ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall    TypenameLoc = Tok.getLocation();
4429cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    ConsumeToken();
4439cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = true;
4449cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
4459cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  else
4469cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = false;
4479cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
4489cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Parse nested-name-specifier.
449b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
4509cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
4519cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Check nested-name specifier.
4529cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (SS.isInvalid()) {
4539cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
454d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
4559cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
4561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
457193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  // Parse the unqualified-id. We allow parsing of both constructor and
45812c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // destructor names and allow the action module to diagnose any semantic
45912c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // errors.
46012c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  UnqualifiedId Name;
461193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  if (ParseUnqualifiedId(SS,
46212c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*EnteringContext=*/false,
46312c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*AllowDestructorName=*/true,
464193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                         /*AllowConstructorName=*/true,
465b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                         ParsedType(),
46612c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         Name)) {
4679cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
468d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
4699cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
470193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
4710b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
472162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
473162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  // Maybe this is an alias-declaration.
474162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  bool IsAliasDecl = Tok.is(tok::equal);
475162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  TypeResult TypeAlias;
476162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (IsAliasDecl) {
4773e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    // TODO: Attribute support. C++0x attributes may appear before the equals.
4783e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    // Where can GNU attributes appear?
479162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    ConsumeToken();
480162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
481162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    if (!getLang().CPlusPlus0x)
482162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(Tok.getLocation(), diag::ext_alias_declaration);
483162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
4843e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    // Type alias templates cannot be specialized.
4853e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    int SpecKind = -1;
486536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&
487536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith        Name.getKind() == UnqualifiedId::IK_TemplateId)
4883e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 0;
4893e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)
4903e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 1;
4913e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
4923e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 2;
4933e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (SpecKind != -1) {
4943e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SourceRange Range;
4953e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      if (SpecKind == 0)
4963e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        Range = SourceRange(Name.TemplateId->LAngleLoc,
4973e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                            Name.TemplateId->RAngleLoc);
4983e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      else
4993e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        Range = TemplateInfo.getSourceRange();
5003e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      Diag(Range.getBegin(), diag::err_alias_declaration_specialization)
5013e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        << SpecKind << Range;
5023e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SkipUntil(tok::semi);
5033e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      return 0;
5043e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    }
5053e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
506162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    // Name must be an identifier.
507162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    if (Name.getKind() != UnqualifiedId::IK_Identifier) {
508162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(Name.StartLocation, diag::err_alias_declaration_not_identifier);
509162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      // No removal fixit: can't recover from this.
510162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      SkipUntil(tok::semi);
511162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      return 0;
512162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    } else if (IsTypeName)
513162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(TypenameLoc, diag::err_alias_declaration_not_identifier)
514162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        << FixItHint::CreateRemoval(SourceRange(TypenameLoc,
515162e1c1b487352434552147967c3dd296ebee2f7Richard Smith                             SS.isNotEmpty() ? SS.getEndLoc() : TypenameLoc));
516162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    else if (SS.isNotEmpty())
517162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
518162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        << FixItHint::CreateRemoval(SS.getRange());
519162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
5203e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    TypeAlias = ParseTypeName(0, TemplateInfo.Kind ?
5213e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                              Declarator::AliasTemplateContext :
522c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                              Declarator::AliasDeclContext, 0, AS, OwnedType);
523162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  } else
524162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    // Parse (optional) attributes (most likely GNU strong-using extension).
525162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    MaybeParseGNUAttributes(attrs);
5261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5279cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Eat ';'.
5289cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  DeclEnd = Tok.getLocation();
5299cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
530162e1c1b487352434552147967c3dd296ebee2f7Richard Smith                   !attrs.empty() ? "attributes list" :
531162e1c1b487352434552147967c3dd296ebee2f7Richard Smith                   IsAliasDecl ? "alias declaration" : "using declaration",
53212c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                   tok::semi);
5339cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
53478b810559d89e996e00684335407443936ce34a1John McCall  // Diagnose an attempt to declare a templated using-declaration.
5353e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  // In C++0x, alias-declarations can be templates:
536162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  //   template <...> using id = type;
5373e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  if (TemplateInfo.Kind && !IsAliasDecl) {
53878b810559d89e996e00684335407443936ce34a1John McCall    SourceRange R = TemplateInfo.getSourceRange();
53978b810559d89e996e00684335407443936ce34a1John McCall    Diag(UsingLoc, diag::err_templated_using_declaration)
54078b810559d89e996e00684335407443936ce34a1John McCall      << R << FixItHint::CreateRemoval(R);
54178b810559d89e996e00684335407443936ce34a1John McCall
54278b810559d89e996e00684335407443936ce34a1John McCall    // Unfortunately, we have to bail out instead of recovering by
54378b810559d89e996e00684335407443936ce34a1John McCall    // ignoring the parameters, just in case the nested name specifier
54478b810559d89e996e00684335407443936ce34a1John McCall    // depends on the parameters.
54578b810559d89e996e00684335407443936ce34a1John McCall    return 0;
54678b810559d89e996e00684335407443936ce34a1John McCall  }
54778b810559d89e996e00684335407443936ce34a1John McCall
5483e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  if (IsAliasDecl) {
5493e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
5503e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    MultiTemplateParamsArg TemplateParamsArg(Actions,
5513e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      TemplateParams ? TemplateParams->data() : 0,
5523e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      TemplateParams ? TemplateParams->size() : 0);
5533e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,
5543e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                         UsingLoc, Name, TypeAlias);
5553e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
556162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
5578113ecfa4e41e2c888b1794389dfe3bce6386493Ted Kremenek  return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS,
5587f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                       Name, attrs.getList(),
5597f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                       IsTypeName, TypenameLoc);
560f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
561f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
562c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// ParseStaticAssertDeclaration - Parse C++0x or C1X static_assert-declaration.
563511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
564c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// [C++0x] static_assert-declaration:
565c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///           static_assert ( constant-expression  ,  string-literal  ) ;
566c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///
567c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// [C1X]   static_assert-declaration:
568c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///           _Static_assert ( constant-expression  ,  string-literal  ) ;
569511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
570d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
571c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne  assert((Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) &&
572c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne         "Not a static_assert declaration");
573c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne
574c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne  if (Tok.is(tok::kw__Static_assert) && !getLang().C1X)
575c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne    Diag(Tok, diag::ext_c1x_static_assert);
576c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne
577511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation StaticAssertLoc = ConsumeToken();
5781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
579511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (Tok.isNot(tok::l_paren)) {
580511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_lparen);
581d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
582511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
5831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
584511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation LParenLoc = ConsumeParen();
585e0762c92110dfdcdd207db461a4ea17afd168f1eDouglas Gregor
58660d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult AssertExpr(ParseConstantExpression());
587511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (AssertExpr.isInvalid()) {
588511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    SkipUntil(tok::semi);
589d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
590511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
5911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
592ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
593d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
594ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson
595511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (Tok.isNot(tok::string_literal)) {
596511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_string_literal);
597511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    SkipUntil(tok::semi);
598d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
599511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
6001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60160d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult AssertMessage(ParseStringLiteralExpression());
6021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (AssertMessage.isInvalid())
603d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
604511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
605a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
6061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60797144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
6089ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor  ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert);
609511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
6109ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc,
6119ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                              AssertExpr.take(),
612a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                              AssertMessage.take(),
613a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                              RParenLoc);
614511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson}
615511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
6166fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// ParseDecltypeSpecifier - Parse a C++0x decltype specifier.
6176fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
6186fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 'decltype' ( expression )
6196fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
6206fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlssonvoid Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
6216fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  assert(Tok.is(tok::kw_decltype) && "Not a decltype specifier");
6226fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
6236fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation StartLoc = ConsumeToken();
6246fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation LParenLoc = Tok.getLocation();
6251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
6276fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson                       "decltype")) {
6286fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    SkipUntil(tok::r_paren);
6296fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
6306fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  }
6311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6326fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Parse the expression
6331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6346fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // C++0x [dcl.type.simple]p4:
6356fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  //   The operand of the decltype specifier is an unevaluated operand.
6366fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  EnterExpressionEvaluationContext Unevaluated(Actions,
637f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                               Sema::Unevaluated);
63860d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Result = ParseExpression();
6396fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (Result.isInvalid()) {
6406fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    SkipUntil(tok::r_paren);
6416fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
6426fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  }
6431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6446fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Match the ')'
6456fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation RParenLoc;
6466fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (Tok.is(tok::r_paren))
6476fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    RParenLoc = ConsumeParen();
6486fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  else
6496fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    MatchRHSPunctuation(tok::r_paren, LParenLoc);
6501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6516fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (RParenLoc.isInvalid())
6526fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
6536fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
6546fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  const char *PrevSpec = 0;
655fec54013fcd0eb72642741584ca04c1bc292bef8John McCall  unsigned DiagID;
6566fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Check for duplicate type specifiers (e.g. "int decltype(a)").
6571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec,
658fec54013fcd0eb72642741584ca04c1bc292bef8John McCall                         DiagID, Result.release()))
659fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
6606fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson}
6616fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
662db5d44b775c60166074acd184ca9f1981c10c2a7Sean Huntvoid Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) {
663db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  assert(Tok.is(tok::kw___underlying_type) &&
664db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt         "Not an underlying type specifier");
665db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
666db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  SourceLocation StartLoc = ConsumeToken();
667db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  SourceLocation LParenLoc = Tok.getLocation();
668db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
669db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
670db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt                       "__underlying_type")) {
671db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    SkipUntil(tok::r_paren);
672db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
673db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  }
674db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
675db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  TypeResult Result = ParseTypeName();
676db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  if (Result.isInvalid()) {
677db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    SkipUntil(tok::r_paren);
678db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
679db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  }
680db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
681db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  // Match the ')'
682db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  SourceLocation RParenLoc;
683db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  if (Tok.is(tok::r_paren))
684db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    RParenLoc = ConsumeParen();
685db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  else
686db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    MatchRHSPunctuation(tok::r_paren, LParenLoc);
687db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
688db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  if (RParenLoc.isInvalid())
689db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
690db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
691db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  const char *PrevSpec = 0;
692db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  unsigned DiagID;
693ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec,
694db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt                         DiagID, Result.release()))
695db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    Diag(StartLoc, DiagID) << PrevSpec;
696db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt}
697db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
69842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// ParseClassName - Parse a C++ class-name, which names a class. Note
69942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// that we only check that the result names a type; semantic analysis
70042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// will need to verify that the type names a class. The result is
7017f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor/// either a type or NULL, depending on whether a type name was
70242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// found.
70342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///
70442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///       class-name: [C++ 9.1]
70542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///         identifier
7067f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor///         simple-template-id
7071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
70831a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas GregorParser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
709059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                          CXXScopeSpec &SS) {
7107f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  // Check whether we have a template-id that names a type.
7117f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  if (Tok.is(tok::annot_template_id)) {
71225a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
713d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor    if (TemplateId->Kind == TNK_Type_template ||
714d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor        TemplateId->Kind == TNK_Dependent_template_name) {
715059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
7167f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
7177f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
718b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      ParsedType Type = getTypeAnnotation(Tok);
7197f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      EndLocation = Tok.getAnnotationEndLoc();
7207f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      ConsumeToken();
72131a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor
72231a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      if (Type)
72331a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor        return Type;
72431a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      return true;
7257f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    }
7267f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
7277f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    // Fall through to produce an error below.
7287f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  }
7297f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
73042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  if (Tok.isNot(tok::identifier)) {
7311ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_class_name);
73231a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
73342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
73442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
73584d0a19828599e8623223632d59447fd498999cfDouglas Gregor  IdentifierInfo *Id = Tok.getIdentifierInfo();
73684d0a19828599e8623223632d59447fd498999cfDouglas Gregor  SourceLocation IdLoc = ConsumeToken();
73784d0a19828599e8623223632d59447fd498999cfDouglas Gregor
73884d0a19828599e8623223632d59447fd498999cfDouglas Gregor  if (Tok.is(tok::less)) {
73984d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // It looks the user intended to write a template-id here, but the
74084d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // template-name was wrong. Try to fix that.
74184d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateNameKind TNK = TNK_Type_template;
74284d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateTy Template;
74323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(),
744059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                             &SS, Template, TNK)) {
74584d0a19828599e8623223632d59447fd498999cfDouglas Gregor      Diag(IdLoc, diag::err_unknown_template_name)
74684d0a19828599e8623223632d59447fd498999cfDouglas Gregor        << Id;
74784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    }
748193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
74984d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (!Template)
75084d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
75184d0a19828599e8623223632d59447fd498999cfDouglas Gregor
752193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam    // Form the template name
75384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    UnqualifiedId TemplateName;
75484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateName.setIdentifier(Id, IdLoc);
755193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
75684d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // Parse the full template-id, then turn it into a type.
75784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName,
75884d0a19828599e8623223632d59447fd498999cfDouglas Gregor                                SourceLocation(), true))
75984d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
76084d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (TNK == TNK_Dependent_template_name)
761059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
762193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
76384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // If we didn't end up with a typename token, there's nothing more we
76484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // can do.
76584d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (Tok.isNot(tok::annot_typename))
76684d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
767193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
76884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // Retrieve the type from the annotation token, consume that token, and
76984d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // return.
77084d0a19828599e8623223632d59447fd498999cfDouglas Gregor    EndLocation = Tok.getAnnotationEndLoc();
771b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    ParsedType Type = getTypeAnnotation(Tok);
77284d0a19828599e8623223632d59447fd498999cfDouglas Gregor    ConsumeToken();
77384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    return Type;
77484d0a19828599e8623223632d59447fd498999cfDouglas Gregor  }
77584d0a19828599e8623223632d59447fd498999cfDouglas Gregor
77642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // We have an identifier; check whether it is actually a type.
777059101f922de6eb765601459925f4c8914420b23Douglas Gregor  ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true,
7789e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor                                        false, ParsedType(),
7799e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor                                        /*NonTrivialTypeSourceInfo=*/true);
780193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  if (!Type) {
781124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor    Diag(IdLoc, diag::err_expected_class_name);
78231a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
78342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
78442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
78542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Consume the identifier.
78684d0a19828599e8623223632d59447fd498999cfDouglas Gregor  EndLocation = IdLoc;
7875606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
7885606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  // Fake up a Declarator to use with ActOnTypeName.
7890b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  DeclSpec DS(AttrFactory);
7905606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetRangeStart(IdLoc);
7915606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetRangeEnd(EndLocation);
792059101f922de6eb765601459925f4c8914420b23Douglas Gregor  DS.getTypeSpecScope() = SS;
7935606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
7945606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  const char *PrevSpec = 0;
7955606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  unsigned DiagID;
7965606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type);
7975606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
7985606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
7995606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
80042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor}
80142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
802e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
803e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
804e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that
805d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl/// cannot start a definition. If SuppressDeclarations is true, we do know.
806e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
807e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-specifier: [C++ class]
808e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}'
809e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}' attributes[opt]
810e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-head:
811e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key identifier[opt] base-clause[opt]
812e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier identifier base-clause[opt]
813e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier[opt] simple-template-id
814e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          base-clause[opt]
815e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   class-key attributes[opt] identifier[opt] base-clause[opt]
8161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier
817e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          identifier base-clause[opt]
8181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier[opt]
819e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          simple-template-id base-clause[opt]
820e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-key:
821e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'class'
822e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
823e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
824e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
825e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       elaborated-type-specifier: [C++ dcl.type.elab]
8261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] identifier
8271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
8281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///                          simple-template-id
829e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
830e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  Note that the C++ class-specifier and elaborated-type-specifier,
831e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  together, subsume the C99 struct-or-union-specifier:
832e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
833e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union-specifier: [C99 6.7.2.1]
834e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier[opt] '{' struct-contents '}'
835e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier
836e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier[opt] '{' struct-contents
837e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                                                         '}' attributes[opt]
838e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier
839e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union:
840e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
841e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
8424c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattnervoid Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
8434c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner                                 SourceLocation StartLoc, DeclSpec &DS,
8444d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                 const ParsedTemplateInfo &TemplateInfo,
845d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl                                 AccessSpecifier AS, bool SuppressDeclarations){
8464c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  DeclSpec::TST TagType;
8474c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  if (TagTokKind == tok::kw_struct)
8484c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_struct;
8494c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  else if (TagTokKind == tok::kw_class)
8504c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_class;
8514c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  else {
8524c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    assert(TagTokKind == tok::kw_union && "Not a class specifier");
8534c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_union;
8544c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  }
855e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
856374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  if (Tok.is(tok::code_completion)) {
857374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor    // Code completion for a struct, class, or union name.
85823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteTag(getCurScope(), TagType);
8597d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return cutOffParsing();
860374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  }
861193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
862926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // C++03 [temp.explicit] 14.7.2/8:
863926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //   The usual access checking rules do not apply to names used to specify
864926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //   explicit instantiations.
865926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //
866926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // As an extension we do not perform access checking on the names used to
867926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // specify explicit specializations either. This is important to allow
868926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // specializing traits classes for private types.
869926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  bool SuppressingAccessChecks = false;
870926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
871926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth      TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization) {
872926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth    Actions.ActOnStartSuppressingAccessChecks();
873926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth    SuppressingAccessChecks = true;
874926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  }
875926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
8760b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
877e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If attributes exist after tag, parse them.
878e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw___attribute))
8797f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
880e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
881f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff  // If declspecs exist after tag, parse them.
882b1d397c23e1f8fd8b404d5731d531e7500f7140dJohn McCall  while (Tok.is(tok::kw___declspec))
8837f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseMicrosoftDeclSpec(attrs);
884193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
885bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // If C++0x attributes exist here, parse them.
886bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Are we consistent with the ordering of parsing of different
887bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // styles of attributes?
8887f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseCXX0XAttributes(attrs);
8891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
89020c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley  if (TagType == DeclSpec::TST_struct &&
891b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      !Tok.is(tok::identifier) &&
892b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      Tok.getIdentifierInfo() &&
893b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      (Tok.is(tok::kw___is_arithmetic) ||
894b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_convertible) ||
89520c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley       Tok.is(tok::kw___is_empty) ||
896b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_floating_point) ||
897b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_function) ||
89820c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley       Tok.is(tok::kw___is_fundamental) ||
899b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_integral) ||
900b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_member_function_pointer) ||
901b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_member_pointer) ||
902b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_pod) ||
903b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_pointer) ||
904b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_same) ||
905877222e2491bbc40a5c74cc100c540983f306b70Douglas Gregor       Tok.is(tok::kw___is_scalar) ||
906b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_signed) ||
907b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_unsigned) ||
908b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_void))) {
909688761409155b47c39eb5dae1b8c6c8a9f43307aDouglas Gregor    // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the
910b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // name of struct templates, but some are keywords in GCC >= 4.3
911b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // and Clang. Therefore, when we see the token sequence "struct
912b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // X", make X into a normal identifier rather than a keyword, to
913b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // allow libstdc++ 4.2 and libc++ to work properly.
914646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
915b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.setKind(tok::identifier);
916b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  }
9171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
918eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse the (optional) nested-name-specifier.
919aa87d33309f505b68c3bfc17486c93e4d224b24fJohn McCall  CXXScopeSpec &SS = DS.getTypeSpecScope();
92008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  if (getLang().CPlusPlus) {
92108d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    // "FOO : BAR" is not a potential typo for "FOO::BAR".
92208d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    ColonProtectionRAIIObject X(*this);
923193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
924b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), true))
925207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      DS.SetTypeSpecError();
9269ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall    if (SS.isSet())
92708d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner      if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
92808d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner        Diag(Tok, diag::err_expected_ident);
92908d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  }
930cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
9312cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor  TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
9322cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor
933cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  // Parse the (optional) class name or simple-template-id.
934e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  IdentifierInfo *Name = 0;
935e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation NameLoc;
93639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  TemplateIdAnnotation *TemplateId = 0;
937e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::identifier)) {
938e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    Name = Tok.getIdentifierInfo();
939e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    NameLoc = ConsumeToken();
940193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
9415ee3734c0b5222a7c445591a1f14102c1b3a289bDouglas Gregor    if (Tok.is(tok::less) && getLang().CPlusPlus) {
942193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      // The name was supposed to refer to a template, but didn't.
9432cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // Eat the template argument list and try to continue parsing this as
9442cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // a class (or template thereof).
9452cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      TemplateArgList TemplateArgs;
9462cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      SourceLocation LAngleLoc, RAngleLoc;
947059101f922de6eb765601459925f4c8914420b23Douglas Gregor      if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, SS,
9482cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor                                           true, LAngleLoc,
949314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor                                           TemplateArgs, RAngleLoc)) {
9502cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // We couldn't parse the template argument list at all, so don't
9512cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // try to give any location information for the list.
9522cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        LAngleLoc = RAngleLoc = SourceLocation();
9532cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
954193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
9552cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      Diag(NameLoc, diag::err_explicit_spec_non_template)
956c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
9572cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << (TagType == DeclSpec::TST_class? 0
9582cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor            : TagType == DeclSpec::TST_struct? 1
9592cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor            : 2)
9602cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << Name
9612cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << SourceRange(LAngleLoc, RAngleLoc);
962193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
963193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      // Strip off the last template parameter list if it was empty, since
964c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      // we've removed its template argument list.
965c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
966c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        if (TemplateParams && TemplateParams->size() > 1) {
967c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams->pop_back();
968c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        } else {
969c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams = 0;
970193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam          const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
971c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor            = ParsedTemplateInfo::NonTemplate;
972c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        }
973c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      } else if (TemplateInfo.Kind
974c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor                                == ParsedTemplateInfo::ExplicitInstantiation) {
975c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        // Pretend this is just a forward declaration.
9762cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        TemplateParams = 0;
977193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam        const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
9782cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor          = ParsedTemplateInfo::NonTemplate;
979193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam        const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc
980c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
981c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc
982c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
9832cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
9842cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor    }
98539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  } else if (Tok.is(tok::annot_template_id)) {
98625a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis    TemplateId = takeTemplateIdAnnotation(Tok);
98739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    NameLoc = ConsumeToken();
988cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
989059101f922de6eb765601459925f4c8914420b23Douglas Gregor    if (TemplateId->Kind != TNK_Type_template &&
990059101f922de6eb765601459925f4c8914420b23Douglas Gregor        TemplateId->Kind != TNK_Dependent_template_name) {
99139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // The template-name in the simple-template-id refers to
99239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // something other than a class template. Give an appropriate
99339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // error message and skip to the ';'.
99439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SourceRange Range(NameLoc);
99539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      if (SS.isNotEmpty())
99639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        Range.setBegin(SS.getBeginLoc());
99739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
99839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
99939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        << Name << static_cast<int>(TemplateId->Kind) << Range;
10001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
100139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      DS.SetTypeSpecError();
100239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SkipUntil(tok::semi, false, true);
1003926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth      if (SuppressingAccessChecks)
1004926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth        Actions.ActOnStopSuppressingAccessChecks();
1005926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
100639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      return;
1007cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    }
1008e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1009e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1010926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // As soon as we're finished parsing the class's template-id, turn access
1011926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // checking back on.
1012926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  if (SuppressingAccessChecks)
1013926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth    Actions.ActOnStopSuppressingAccessChecks();
1014926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
101567d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  // There are four options here.  If we have 'struct foo;', then this
101667d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  // is either a forward declaration or a friend declaration, which
1017cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson  // have to be treated differently.  If we have 'struct foo {...',
10181d20927fd0a08c26ef0e86e26f42073fd582ff77Anders Carlsson  // 'struct foo :...' or 'struct foo final[opt]' then this is a
1019cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson  // definition. Otherwise we have something like 'struct foo xyz', a reference.
1020d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // However, in some contexts, things look like declarations but are just
1021d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // references, e.g.
1022d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // new struct s;
1023d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // or
1024d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // &T::operator struct s;
1025d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // For these, SuppressDeclarations is true.
1026f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  Sema::TagUseKind TUK;
1027d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  if (SuppressDeclarations)
1028f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = Sema::TUK_Reference;
1029cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson  else if (Tok.is(tok::l_brace) ||
1030cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson           (getLang().CPlusPlus && Tok.is(tok::colon)) ||
10318a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson           isCXX0XFinalKeyword()) {
1032d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    if (DS.isFriendSpecified()) {
1033d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // C++ [class.friend]p2:
1034d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      //   A class shall not be defined in a friend declaration.
1035d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      Diag(Tok.getLocation(), diag::err_friend_decl_defines_class)
1036d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor        << SourceRange(DS.getFriendSpecLoc());
1037d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor
1038d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Skip everything up to the semicolon, so that this looks like a proper
1039d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // friend class (or template thereof) declaration.
1040d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      SkipUntil(tok::semi, true, true);
1041f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall      TUK = Sema::TUK_Friend;
1042d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    } else {
1043d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Okay, this is a class definition.
1044f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall      TUK = Sema::TUK_Definition;
1045d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    }
1046d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor  } else if (Tok.is(tok::semi))
1047f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
1048e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  else
1049f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = Sema::TUK_Reference;
1050e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1051207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall  if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error ||
1052f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                               TUK != Sema::TUK_Definition)) {
1053207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall    if (DS.getTypeSpecType() != DeclSpec::TST_error) {
1054207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      // We have a declaration or reference to an anonymous class.
1055207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      Diag(StartLoc, diag::err_anon_type_definition)
1056207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall        << DeclSpec::getSpecifierName(TagType);
1057207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall    }
1058e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1059e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SkipUntil(tok::comma, true);
1060e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    return;
1061e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1062e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1063ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  // Create the tag portion of the class or class template.
1064d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  DeclResult TagOrTempResult = true; // invalid
1065d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  TypeResult TypeResult = true; // invalid
10664d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
1067402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor  bool Owned = false;
1068f1bbbb49f06a7462476cd88166fccda5feb15cabJohn McCall  if (TemplateId) {
10694d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // Explicit specialization, class template partial specialization,
10704d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // or explicit instantiation.
10711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ASTTemplateArgsPtr TemplateArgsPtr(Actions,
107239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->getTemplateArgs(),
107339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->NumArgs);
10744d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1075f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        TUK == Sema::TUK_Declaration) {
10764d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit instantiation of a class template.
10774d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
107823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        = Actions.ActOnExplicitInstantiation(getCurScope(),
107945f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                             TemplateInfo.ExternLoc,
10801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateInfo.TemplateLoc,
10814d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TagType,
10821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             StartLoc,
10834d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             SS,
10842b5289b6fd7e3d9899868410a498c081c9595662John McCall                                             TemplateId->Template,
10851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->TemplateNameLoc,
10861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->LAngleLoc,
10874d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateArgsPtr,
10881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->RAngleLoc,
10897f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                             attrs.getList());
109074256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall
109174256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // Friend template-ids are treated as references unless
109274256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // they have template headers, in which case they're ill-formed
109374256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // (FIXME: "template <class T> friend class A<T>::B<int>;").
109474256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // We diagnose this error in ActOnClassTemplateSpecialization.
1095f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    } else if (TUK == Sema::TUK_Reference ||
1096f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall               (TUK == Sema::TUK_Friend &&
109774256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall                TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
1098059101f922de6eb765601459925f4c8914420b23Douglas Gregor      TypeResult = Actions.ActOnTagTemplateIdType(TUK, TagType,
1099059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  StartLoc,
1100059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->SS,
1101059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->Template,
1102059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->TemplateNameLoc,
1103059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->LAngleLoc,
1104059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateArgsPtr,
1105059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->RAngleLoc);
11064d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    } else {
11074d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit specialization or a class template
11084d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // partial specialization.
11094d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TemplateParameterLists FakedParamLists;
11104d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
11114d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
11124d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // This looks like an explicit instantiation, because we have
11134d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // something like
11144d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
11154d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //   template class Foo<X>
11164d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
11173f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor        // but it actually has a definition. Most likely, this was
11184d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // meant to be an explicit specialization, but the user forgot
11194d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // the '<>' after 'template'.
1120f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        assert(TUK == Sema::TUK_Definition && "Expected a definition here");
11214d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
11221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        SourceLocation LAngleLoc
11234d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
11241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        Diag(TemplateId->TemplateNameLoc,
11254d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor             diag::err_explicit_instantiation_with_definition)
11264d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          << SourceRange(TemplateInfo.TemplateLoc)
1127849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor          << FixItHint::CreateInsertion(LAngleLoc, "<>");
11284d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
11294d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // Create a fake template parameter list that contains only
11304d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // "template<>", so that we treat this construct as a class
11314d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // template specialization.
11324d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        FakedParamLists.push_back(
11331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          Actions.ActOnTemplateParameterList(0, SourceLocation(),
11344d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateInfo.TemplateLoc,
11351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             LAngleLoc,
11361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             0, 0,
11374d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             LAngleLoc));
11384d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        TemplateParams = &FakedParamLists;
11394d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      }
11404d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
11414d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // Build the class template specialization.
11424d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
114323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK,
114439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       StartLoc, SS,
11452b5289b6fd7e3d9899868410a498c081c9595662John McCall                       TemplateId->Template,
11461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->TemplateNameLoc,
11471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->LAngleLoc,
114839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       TemplateArgsPtr,
11491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->RAngleLoc,
11507f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                       attrs.getList(),
1151f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                       MultiTemplateParamsArg(Actions,
1152cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                    TemplateParams? &(*TemplateParams)[0] : 0,
1153cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                 TemplateParams? TemplateParams->size() : 0));
11544d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    }
11553f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1156f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall             TUK == Sema::TUK_Declaration) {
11573f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Explicit instantiation of a member of a class template
11583f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // specialization, e.g.,
11593f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
11603f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //   template struct Outer<int>::Inner;
11613f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
11623f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    TagOrTempResult
116323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      = Actions.ActOnExplicitInstantiation(getCurScope(),
116445f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                           TemplateInfo.ExternLoc,
11651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TemplateInfo.TemplateLoc,
11661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TagType, StartLoc, SS, Name,
11677f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                           NameLoc, attrs.getList());
11689a34edb710917798aa30263374f624f13b594605John McCall  } else if (TUK == Sema::TUK_Friend &&
11699a34edb710917798aa30263374f624f13b594605John McCall             TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
11709a34edb710917798aa30263374f624f13b594605John McCall    TagOrTempResult =
11719a34edb710917798aa30263374f624f13b594605John McCall      Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(),
11729a34edb710917798aa30263374f624f13b594605John McCall                                      TagType, StartLoc, SS,
11737f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                      Name, NameLoc, attrs.getList(),
11749a34edb710917798aa30263374f624f13b594605John McCall                                      MultiTemplateParamsArg(Actions,
11759a34edb710917798aa30263374f624f13b594605John McCall                                    TemplateParams? &(*TemplateParams)[0] : 0,
11769a34edb710917798aa30263374f624f13b594605John McCall                                 TemplateParams? TemplateParams->size() : 0));
11773f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else {
11783f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1179f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        TUK == Sema::TUK_Definition) {
11803f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor      // FIXME: Diagnose this particular error.
11813f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    }
11823f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor
1183c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    bool IsDependent = false;
1184c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
1185a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    // Don't pass down template parameter lists if this is just a tag
1186a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    // reference.  For example, we don't need the template parameters here:
1187a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    //   template <class T> class A *makeA(T t);
1188a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    MultiTemplateParamsArg TParams;
1189a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    if (TUK != Sema::TUK_Reference && TemplateParams)
1190a25c4080a490ea2bab6f54094dd75b19eae83770John McCall      TParams =
1191a25c4080a490ea2bab6f54094dd75b19eae83770John McCall        MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size());
1192a25c4080a490ea2bab6f54094dd75b19eae83770John McCall
11933f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Declaration or definition of a class type
11949a34edb710917798aa30263374f624f13b594605John McCall    TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc,
11957f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                       SS, Name, NameLoc, attrs.getList(), AS,
1196e761230ae3751b525cadd8066c74ec278ee4ef57Douglas Gregor                                       DS.getModulePrivateSpecLoc(),
1197a25c4080a490ea2bab6f54094dd75b19eae83770John McCall                                       TParams, Owned, IsDependent, false,
1198a88cefd266c428be33cc06f7e8b00ff8fc97c1ffAbramo Bagnara                                       false, clang::TypeResult());
1199c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
1200c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // If ActOnTag said the type was dependent, try again with the
1201c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // less common call.
12029a34edb710917798aa30263374f624f13b594605John McCall    if (IsDependent) {
12039a34edb710917798aa30263374f624f13b594605John McCall      assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend);
120423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK,
1205193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                                             SS, Name, StartLoc, NameLoc);
12069a34edb710917798aa30263374f624f13b594605John McCall    }
12073f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  }
1208e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1209e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If there is a body, parse it and inform the actions module.
1210f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  if (TUK == Sema::TUK_Definition) {
1211bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    assert(Tok.is(tok::l_brace) ||
1212cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson           (getLang().CPlusPlus && Tok.is(tok::colon)) ||
12138a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson           isCXX0XFinalKeyword());
121407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    if (getLang().CPlusPlus)
1215212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
121607952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    else
1217212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
1218e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1219e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1220b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  const char *PrevSpec = 0;
1221b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  unsigned DiagID;
1222b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  bool Result;
1223c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  if (!TypeResult.isInvalid()) {
12240daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara    Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
12250daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                NameLoc.isValid() ? NameLoc : StartLoc,
1226b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                PrevSpec, DiagID, TypeResult.get());
1227c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else if (!TagOrTempResult.isInvalid()) {
12280daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara    Result = DS.SetTypeSpecType(TagType, StartLoc,
12290daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                NameLoc.isValid() ? NameLoc : StartLoc,
12300daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                PrevSpec, DiagID, TagOrTempResult.get(), Owned);
1231c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else {
1232ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    DS.SetTypeSpecError();
123366e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson    return;
123466e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson  }
12351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1236b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  if (Result)
1237fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
1238193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
12394ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // At this point, we've successfully parsed a class-specifier in 'definition'
12404ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // form (e.g. "struct foo { int x; }".  While we could just return here, we're
12414ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // going to look at what comes after it to improve error recovery.  If an
12424ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // impossible token occurs next, we assume that the programmer forgot a ; at
12434ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // the end of the declaration and recover that way.
12444ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  //
12454ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // This switch enumerates the valid "follow" set for definition.
1246f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  if (TUK == Sema::TUK_Definition) {
1247b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    bool ExpectedSemi = true;
12484ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    switch (Tok.getKind()) {
1249b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    default: break;
12504ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    case tok::semi:               // struct foo {...} ;
125199c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::star:               // struct foo {...} *         P;
125299c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::amp:                // struct foo {...} &         R = ...
125399c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::identifier:         // struct foo {...} V         ;
125499c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::r_paren:            //(struct foo {...} )         {4}
125599c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_cxxscope:     // struct foo {...} a::       b;
125699c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_typename:     // struct foo {...} a         ::b;
125799c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_template_id:  // struct foo {...} a<int>    ::b;
1258c2e1c1af8ffe750b827284f207b9207112c7cc4eChris Lattner    case tok::l_paren:            // struct foo {...} (         x);
125916acfee729e00536af827935ccfcf69be721e462Chris Lattner    case tok::comma:              // __builtin_offsetof(struct foo{...} ,
1260b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      ExpectedSemi = false;
1261b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      break;
1262b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    // Type qualifiers
1263b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_const:           // struct foo {...} const     x;
1264b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_volatile:        // struct foo {...} volatile  x;
1265b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_restrict:        // struct foo {...} restrict  x;
1266b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_inline:          // struct foo {...} inline    foo() {};
126799c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    // Storage-class specifiers
126899c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_static:          // struct foo {...} static    x;
126999c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_extern:          // struct foo {...} extern    x;
127099c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_typedef:         // struct foo {...} typedef   x;
127199c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_register:        // struct foo {...} register  x;
127299c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_auto:            // struct foo {...} auto      x;
1273af1fc7af351758b0ea0d285bdfe5640128109a4eRichard Smith    case tok::kw_mutable:         // struct foo {...} mutable   x;
1274af1fc7af351758b0ea0d285bdfe5640128109a4eRichard Smith    case tok::kw_constexpr:       // struct foo {...} constexpr x;
1275b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // As shown above, type qualifiers and storage class specifiers absolutely
1276b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // can occur after class specifiers according to the grammar.  However,
1277fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner      // almost no one actually writes code like this.  If we see one of these,
1278b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // it is much more likely that someone missed a semi colon and the
1279b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // type/storage class specifier we're seeing is part of the *next*
1280b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // intended declaration, as in:
1281b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //
1282b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //   struct foo { ... }
1283b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //   typedef int X;
1284b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //
1285b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // We'd really like to emit a missing semicolon error instead of emitting
1286b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // an error on the 'int' saying that you can't have two type specifiers in
1287b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // the same declaration of X.  Because of this, we look ahead past this
1288b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // token to see if it's a type specifier.  If so, we know the code is
1289b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // otherwise invalid, so we can produce the expected semi error.
1290b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      if (!isKnownToBeTypeSpecifier(NextToken()))
1291b3a4e432c90be98c6d918087750397e86d030368Chris Lattner        ExpectedSemi = false;
12924ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      break;
1293193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1294193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam    case tok::r_brace:  // struct bar { struct foo {...} }
12954ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // Missing ';' at end of struct is accepted as an extension in C mode.
1296b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      if (!getLang().CPlusPlus)
1297b3a4e432c90be98c6d918087750397e86d030368Chris Lattner        ExpectedSemi = false;
1298b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      break;
1299b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    }
1300193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1301cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith    // C++ [temp]p3 In a template-declaration which defines a class, no
1302cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith    // declarator is permitted.
1303cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith    if (TemplateInfo.Kind)
1304cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith      ExpectedSemi = true;
1305cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith
1306b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    if (ExpectedSemi) {
13074ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
13084ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner                       TagType == DeclSpec::TST_class ? "class"
13094ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner                       : TagType == DeclSpec::TST_struct? "struct" : "union");
13104ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // Push this token back into the preprocessor and change our current token
13114ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // to ';' so that the rest of the code recovers as though there were an
13124ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // ';' after the definition.
13134ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      PP.EnterToken(Tok);
1314193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      Tok.setKind(tok::semi);
13154ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    }
13164ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  }
1317e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1318e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
13191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
1320e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1321e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-clause : [C++ class.derived]
1322e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ':' base-specifier-list
1323e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier-list:
1324e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier '...'[opt]
1325e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier-list ',' base-specifier '...'[opt]
1326d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseBaseClause(Decl *ClassDecl) {
1327e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  assert(Tok.is(tok::colon) && "Not a base clause");
1328e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  ConsumeToken();
1329e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1330f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Build up an array of parsed base specifiers.
13315f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<CXXBaseSpecifier *, 8> BaseInfo;
1332f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
1333e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  while (true) {
1334e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Parse a base-specifier.
1335f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    BaseResult Result = ParseBaseSpecifier(ClassDecl);
13365ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor    if (Result.isInvalid()) {
1337e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Skip the rest of this base specifier, up until the comma or
1338e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // opening brace.
1339f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      SkipUntil(tok::comma, tok::l_brace, true, true);
1340f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    } else {
1341f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      // Add this to our array of base specifiers.
13425ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor      BaseInfo.push_back(Result.get());
1343e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
1344e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1345e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // If the next token is a comma, consume it and keep reading
1346e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // base-specifiers.
1347e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (Tok.isNot(tok::comma)) break;
13481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1349e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Consume the comma.
1350e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
1351e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1352f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
1353f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Attach the base specifiers
1354beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad  Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size());
1355e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1356e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1357e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
1358e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example:
1359e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///    class foo : public bar, virtual private baz {
1360e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers.
1361e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1362e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier: [C++ class.derived]
1363e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ::[opt] nested-name-specifier[opt] class-name
1364e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt]
1365e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                        class-name
1366e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
1367e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                        class-name
1368d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {
1369e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  bool IsVirtual = false;
1370e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation StartLoc = Tok.getLocation();
1371e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1372e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword.
1373e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
1374e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
1375e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
1376e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1377e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1378e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse an (optional) access specifier.
1379e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  AccessSpecifier Access = getAccessSpecifierIfPresent();
138092f883177b162928a8e632e4e3b93fafd2b26072John McCall  if (Access != AS_none)
1381e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
13821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1383e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword (again!), in case it came after the
1384e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // access specifier.
1385e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
1386e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SourceLocation VirtualLoc = ConsumeToken();
1387e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (IsVirtual) {
1388e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Complain about duplicate 'virtual'
13891ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner      Diag(VirtualLoc, diag::err_dup_virtual)
1390849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor        << FixItHint::CreateRemoval(VirtualLoc);
1391e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
1392e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1393e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
1394e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1395e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1396eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse optional '::' and optional nested-name-specifier.
1397eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  CXXScopeSpec SS;
1398b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
1399e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1400e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // The location of the base class itself.
1401e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation BaseLoc = Tok.getLocation();
140242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
140342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Parse the class-name.
14047f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceLocation EndLocation;
1405059101f922de6eb765601459925f4c8914420b23Douglas Gregor  TypeResult BaseType = ParseClassName(EndLocation, SS);
140631a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor  if (BaseType.isInvalid())
140742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor    return true;
14081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1409f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // Parse the optional ellipsis (for a pack expansion). The ellipsis is
1410f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // actually part of the base-specifier-list grammar productions, but we
1411f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // parse it here for convenience.
1412f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  SourceLocation EllipsisLoc;
1413f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  if (Tok.is(tok::ellipsis))
1414f90b27ad077c3339b62befc892382845339f9490Douglas Gregor    EllipsisLoc = ConsumeToken();
1415f90b27ad077c3339b62befc892382845339f9490Douglas Gregor
14161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Find the complete source range for the base-specifier.
14177f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceRange Range(StartLoc, EndLocation);
14181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1419e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Notify semantic analysis that we have parsed a complete
1420e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // base-specifier.
1421a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl  return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
1422f90b27ad077c3339b62befc892382845339f9490Douglas Gregor                                    BaseType.get(), BaseLoc, EllipsisLoc);
1423e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1424e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1425e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is
1426e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier.
1427e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1428e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       access-specifier: [C++ class.derived]
1429e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'private'
1430e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'protected'
1431e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'public'
14321eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAccessSpecifier Parser::getAccessSpecifierIfPresent() const {
1433e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  switch (Tok.getKind()) {
1434e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  default: return AS_none;
1435e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_private: return AS_private;
1436e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_protected: return AS_protected;
1437e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_public: return AS_public;
1438e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1439e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
14404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1441d33133cdc1af466f9c276249b2621be03867888bEli Friedmanvoid Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
1442d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall                                             Decl *ThisDecl) {
1443d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // We just declared a member function. If this member function
1444d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // has any default arguments, we'll need to parse them later.
1445d33133cdc1af466f9c276249b2621be03867888bEli Friedman  LateParsedMethodDeclaration *LateMethod = 0;
14461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  DeclaratorChunk::FunctionTypeInfo &FTI
1447075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara    = DeclaratorInfo.getFunctionTypeInfo();
1448d33133cdc1af466f9c276249b2621be03867888bEli Friedman  for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
1449d33133cdc1af466f9c276249b2621be03867888bEli Friedman    if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
1450d33133cdc1af466f9c276249b2621be03867888bEli Friedman      if (!LateMethod) {
1451d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Push this method onto the stack of late-parsed method
1452d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // declarations.
1453d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
1454d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
145523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        LateMethod->TemplateScope = getCurScope()->isTemplateParamScope();
1456d33133cdc1af466f9c276249b2621be03867888bEli Friedman
1457d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Add all of the parameters prior to this one (they don't
1458d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // have default arguments).
1459d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateMethod->DefaultArgs.reserve(FTI.NumArgs);
1460d33133cdc1af466f9c276249b2621be03867888bEli Friedman        for (unsigned I = 0; I < ParamIdx; ++I)
1461d33133cdc1af466f9c276249b2621be03867888bEli Friedman          LateMethod->DefaultArgs.push_back(
14628f8210c47797f013e0fb24a26f9c4751b10783feDouglas Gregor                             LateParsedDefaultArgument(FTI.ArgInfo[I].Param));
1463d33133cdc1af466f9c276249b2621be03867888bEli Friedman      }
1464d33133cdc1af466f9c276249b2621be03867888bEli Friedman
1465d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // Add this parameter to the list of parameters (it or may
1466d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // not have a default argument).
1467d33133cdc1af466f9c276249b2621be03867888bEli Friedman      LateMethod->DefaultArgs.push_back(
1468d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
1469d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                  FTI.ArgInfo[ParamIdx].DefaultArgTokens));
1470d33133cdc1af466f9c276249b2621be03867888bEli Friedman    }
1471d33133cdc1af466f9c276249b2621be03867888bEli Friedman  }
1472d33133cdc1af466f9c276249b2621be03867888bEli Friedman}
1473d33133cdc1af466f9c276249b2621be03867888bEli Friedman
14741f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// isCXX0XVirtSpecifier - Determine whether the next token is a C++0x
14751f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier.
14761f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
14771f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier:
14781f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         override
14791f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         final
1480cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders CarlssonVirtSpecifiers::Specifier Parser::isCXX0XVirtSpecifier() const {
1481ce93a7cee6c0ea979c12b278771a79c4d6a37fc0Anders Carlsson  if (!getLang().CPlusPlus)
1482cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson    return VirtSpecifiers::VS_None;
1483cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
1484b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  if (Tok.is(tok::identifier)) {
1485b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    IdentifierInfo *II = Tok.getIdentifierInfo();
14861f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
14877eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    // Initialize the contextual keywords.
14887eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    if (!Ident_final) {
14897eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson      Ident_final = &PP.getIdentifierTable().get("final");
14907eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson      Ident_override = &PP.getIdentifierTable().get("override");
14917eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    }
14927eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson
1493b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (II == Ident_override)
1494b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return VirtSpecifiers::VS_Override;
14951f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
1496b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (II == Ident_final)
1497b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return VirtSpecifiers::VS_Final;
1498b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  }
1499b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
1500b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  return VirtSpecifiers::VS_None;
15011f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson}
15021f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
15031f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// ParseOptionalCXX0XVirtSpecifierSeq - Parse a virt-specifier-seq.
15041f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
15051f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier-seq:
15061f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier
15071f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier-seq virt-specifier
1508b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlssonvoid Parser::ParseOptionalCXX0XVirtSpecifierSeq(VirtSpecifiers &VS) {
1509b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  while (true) {
1510cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson    VirtSpecifiers::Specifier Specifier = isCXX0XVirtSpecifier();
1511b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (Specifier == VirtSpecifiers::VS_None)
1512b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return;
1513b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
1514b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    // C++ [class.mem]p8:
1515b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    //   A virt-specifier-seq shall contain at most one of each virt-specifier.
1516cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson    const char *PrevSpec = 0;
151746127a96b6dd6b93aa18d5f7a55bc2db8b52a2c9Anders Carlsson    if (VS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec))
1518b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier)
1519b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson        << PrevSpec
1520b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson        << FixItHint::CreateRemoval(Tok.getLocation());
1521b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
1522ce93a7cee6c0ea979c12b278771a79c4d6a37fc0Anders Carlsson    if (!getLang().CPlusPlus0x)
1523ce93a7cee6c0ea979c12b278771a79c4d6a37fc0Anders Carlsson      Diag(Tok.getLocation(), diag::ext_override_control_keyword)
1524ce93a7cee6c0ea979c12b278771a79c4d6a37fc0Anders Carlsson        << VirtSpecifiers::getSpecifierName(Specifier);
1525b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    ConsumeToken();
1526b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  }
15271f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson}
15281f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
15298a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson/// isCXX0XFinalKeyword - Determine whether the next token is a C++0x
15308a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson/// contextual 'final' keyword.
15318a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlssonbool Parser::isCXX0XFinalKeyword() const {
1532ce93a7cee6c0ea979c12b278771a79c4d6a37fc0Anders Carlsson  if (!getLang().CPlusPlus)
15338a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    return false;
1534cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
15358a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  if (!Tok.is(tok::identifier))
15368a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    return false;
1537cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
15388a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  // Initialize the contextual keywords.
15398a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  if (!Ident_final) {
15408a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    Ident_final = &PP.getIdentifierTable().get("final");
15418a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    Ident_override = &PP.getIdentifierTable().get("override");
1542cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson  }
15438a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson
15448a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  return Tok.getIdentifierInfo() == Ident_final;
1545cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson}
1546cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
15474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
15484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
15494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declaration:
15504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         decl-specifier-seq[opt] member-declarator-list[opt] ';'
15514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         function-definition ';'[opt]
15524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
15534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         using-declaration                                            [TODO]
1554511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration
15555aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson///         template-declaration
1556bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU]   '__extension__' member-declaration
15574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
15584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator-list:
15594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator
15604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator-list ',' member-declarator
15614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
15624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator:
15631f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         declarator virt-specifier-seq[opt] pure-specifier[opt]
15644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         declarator constant-initializer[opt]
15657a614d8380297fcd2bc23986241905d97222948cRichard Smith/// [C++11] declarator brace-or-equal-initializer[opt]
15664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         identifier[opt] ':' constant-expression
15674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
15681f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier-seq:
15691f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier
15701f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier-seq virt-specifier
15711f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
15721f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier:
15731f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         override
15741f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         final
15751f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         new
15761f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
1577e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl///       pure-specifier:
15784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '= 0'
15794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
15804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       constant-initializer:
15814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '=' constant-expression
15824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
158337b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregorvoid Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
1584c9068d7dd94d439cec66c421115d15303e481025John McCall                                       const ParsedTemplateInfo &TemplateInfo,
1585c9068d7dd94d439cec66c421115d15303e481025John McCall                                       ParsingDeclRAIIObject *TemplateDiags) {
15868a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor  if (Tok.is(tok::at)) {
15878a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    if (getLang().ObjC1 && NextToken().isObjCAtKeyword(tok::objc_defs))
15888a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor      Diag(Tok, diag::err_at_defs_cxx);
15898a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    else
15908a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor      Diag(Tok, diag::err_at_in_class);
15918a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor
15928a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    ConsumeToken();
15938a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    SkipUntil(tok::r_brace);
15948a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    return;
15958a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor  }
15968a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor
159760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  // Access declarations.
159860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  if (!TemplateInfo.Kind &&
159960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) &&
16009ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall      !TryAnnotateCXXScopeToken() &&
160160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      Tok.is(tok::annot_cxxscope)) {
160260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    bool isAccessDecl = false;
160360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    if (NextToken().is(tok::identifier))
160460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      isAccessDecl = GetLookAheadToken(2).is(tok::semi);
160560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    else
160660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      isAccessDecl = NextToken().is(tok::kw_operator);
160760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
160860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    if (isAccessDecl) {
160960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // Collect the scope specifier token we annotated earlier.
161060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      CXXScopeSpec SS;
1611b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
161260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
161360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // Try to parse an unqualified-id.
161460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      UnqualifiedId Name;
1615b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), Name)) {
161660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        SkipUntil(tok::semi);
161760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        return;
161860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      }
161960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
162060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // TODO: recover from mistakenly-qualified operator declarations.
162160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      if (ExpectAndConsume(tok::semi,
162260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           diag::err_expected_semi_after,
162360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           "access declaration",
162460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           tok::semi))
162560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        return;
162660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
162723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.ActOnUsingDeclaration(getCurScope(), AS,
162860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    false, SourceLocation(),
162960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    SS, Name,
163060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    /* AttrList */ 0,
163160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    /* IsTypeName */ false,
163260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    SourceLocation());
163360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      return;
163460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    }
163560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  }
163660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
1637511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  // static_assert-declaration
1638c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne  if (Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) {
163937b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    // FIXME: Check for templates
164097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
164197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    ParseStaticAssertDeclaration(DeclEnd);
1642682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1643682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
16441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1645682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  if (Tok.is(tok::kw_template)) {
16461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(!TemplateInfo.TemplateParams &&
164737b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor           "Nested template improperly parsed?");
164897144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
16491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd,
16504d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                         AS);
1651682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1652682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
16535aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson
1654bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  // Handle:  member-declaration ::= '__extension__' member-declaration
1655bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  if (Tok.is(tok::kw___extension__)) {
1656bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    // __extension__ silences extension warnings in the subexpression.
1657bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
1658bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ConsumeToken();
1659c9068d7dd94d439cec66c421115d15303e481025John McCall    return ParseCXXClassMemberDeclaration(AS, TemplateInfo, TemplateDiags);
1660bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  }
16619cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
16624ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it
16634ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // is a bitfield.
1664a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner  ColonProtectionRAIIObject X(*this);
1665193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
16660b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributesWithRange attrs(AttrFactory);
1667bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // Optional C++0x attribute-specifier
16687f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseCXX0XAttributes(attrs);
16697f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseMicrosoftAttributes(attrs);
1670bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
16719cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_using)) {
16727f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ProhibitAttributes(attrs);
16731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16749cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    // Eat 'using'.
16759cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SourceLocation UsingLoc = ConsumeToken();
16769cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
16779cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    if (Tok.is(tok::kw_namespace)) {
16789cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      Diag(UsingLoc, diag::err_using_namespace_in_class);
16799cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SkipUntil(tok::semi, true, true);
1680ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    } else {
16819cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SourceLocation DeclEnd;
16823e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      // Otherwise, it must be a using-declaration or an alias-declaration.
168378b810559d89e996e00684335407443936ce34a1John McCall      ParseUsingDeclaration(Declarator::MemberContext, TemplateInfo,
168478b810559d89e996e00684335407443936ce34a1John McCall                            UsingLoc, DeclEnd, AS);
16859cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    }
16869cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return;
16879cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
16889cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
16894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // decl-specifier-seq:
16904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Parse the common declaration-specifiers piece.
1691c9068d7dd94d439cec66c421115d15303e481025John McCall  ParsingDeclSpec DS(*this, TemplateDiags);
16927f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  DS.takeAttributesFrom(attrs);
169337b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor  ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class);
16944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1695f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  MultiTemplateParamsArg TemplateParams(Actions,
1696dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
1697dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
1698dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
16994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::semi)) {
17004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
1701d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decl *TheDecl =
17020f4be74ff0273e505d383f89174ef539828424edChandler Carruth      Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS, TemplateParams);
1703c9068d7dd94d439cec66c421115d15303e481025John McCall    DS.complete(TheDecl);
170467d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    return;
17054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
170607952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
170754abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext);
17084867347e82648d3baf09524b98b09c297a5a198fNico Weber  VirtSpecifiers VS;
17096a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet  ExprResult Init;
17104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1711eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  // Hold late-parsed attributes so we can attach a Decl to them later.
1712eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  LateParsedAttrList LateParsedAttrs;
1713eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
17143a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis  if (Tok.isNot(tok::colon)) {
1715a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner    // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
1716a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner    ColonProtectionRAIIObject X(*this);
1717a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner
17183a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Parse the first declarator.
17193a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    ParseDeclarator(DeclaratorInfo);
17203a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Error parsing the declarator?
172110bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor    if (!DeclaratorInfo.hasName()) {
17223a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      // If so, skip until the semi-colon or a }.
1723d941fa4ff0d0d64b5a541dbd4f99693bff7f6e8dSebastian Redl      SkipUntil(tok::r_brace, true, true);
17243a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (Tok.is(tok::semi))
17253a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeToken();
1726682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
17274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
17284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
17294867347e82648d3baf09524b98b09c297a5a198fNico Weber    ParseOptionalCXX0XVirtSpecifierSeq(VS);
17304867347e82648d3baf09524b98b09c297a5a198fNico Weber
17311b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson    // If attributes exist after the declarator, but before an '{', parse them.
1732eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
17331b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson
17346a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    // MSVC permits pure specifier on inline functions declared at class scope.
17356a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    // Hence check for =0 before checking for function definition.
17366a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    if (getLang().Microsoft && Tok.is(tok::equal) &&
17376a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        DeclaratorInfo.isFunctionDeclarator() &&
17386a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        NextToken().is(tok::numeric_constant)) {
17396a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet      ConsumeToken();
17406a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet      Init = ParseInitializer();
17416a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet      if (Init.isInvalid())
17426a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        SkipUntil(tok::comma, true, true);
17436a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    }
17446a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet
1745e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    bool IsDefinition = false;
17463a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // function-definition:
17477a614d8380297fcd2bc23986241905d97222948cRichard Smith    //
17487a614d8380297fcd2bc23986241905d97222948cRichard Smith    // In C++11, a non-function declarator followed by an open brace is a
17497a614d8380297fcd2bc23986241905d97222948cRichard Smith    // braced-init-list for an in-class member initialization, not an
17507a614d8380297fcd2bc23986241905d97222948cRichard Smith    // erroneous function definition.
17517a614d8380297fcd2bc23986241905d97222948cRichard Smith    if (Tok.is(tok::l_brace) && !getLang().CPlusPlus0x) {
1752e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      IsDefinition = true;
1753e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    } else if (DeclaratorInfo.isFunctionDeclarator()) {
17547a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
1755e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        IsDefinition = true;
1756e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      } else if (Tok.is(tok::equal)) {
1757e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        const Token &KW = NextToken();
1758e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        if (KW.is(tok::kw_default) || KW.is(tok::kw_delete))
1759e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt          IsDefinition = true;
1760e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      }
1761e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    }
1762e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
1763e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    if (IsDefinition) {
17643a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (!DeclaratorInfo.isFunctionDeclarator()) {
17653a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        Diag(Tok, diag::err_func_def_no_params);
17663a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
17673a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        SkipUntil(tok::r_brace, true);
17689ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor
17699ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        // Consume the optional ';'
17709ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        if (Tok.is(tok::semi))
17719ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor          ConsumeToken();
1772682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
17733a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
17743a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis
17753a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
17763a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        Diag(Tok, diag::err_function_declared_typedef);
17773a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // This recovery skips the entire function body. It would be nice
17783a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // to simply call ParseCXXInlineMethodDef() below, however Sema
17793a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // assumes the declarator represents a function, not a typedef.
17803a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
17813a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        SkipUntil(tok::r_brace, true);
17829ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor
17839ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        // Consume the optional ';'
17849ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        if (Tok.is(tok::semi))
17859ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor          ConsumeToken();
1786682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
17873a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
17884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1789eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      Decl *FunDecl =
1790eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski        ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo, VS, Init);
1791eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
1792eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
1793eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski        LateParsedAttrs[i]->setDecl(FunDecl);
1794eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      }
1795eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      LateParsedAttrs.clear();
1796e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
1797e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      // Consume the ';' - it's optional unless we have a delete or default
1798e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      if (Tok.is(tok::semi)) {
17999ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        ConsumeToken();
1800e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      }
18019ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor
1802682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
18033a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    }
18044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
18054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
18064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // member-declarator-list:
18074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator
18084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator-list ',' member-declarator
18094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
18105f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Decl *, 8> DeclsInGroup;
181160d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult BitfieldSize;
18124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
18134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  while (1) {
18144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // member-declarator:
18154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   declarator pure-specifier[opt]
18167a614d8380297fcd2bc23986241905d97222948cRichard Smith    //   declarator brace-or-equal-initializer[opt]
18174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   identifier[opt] ':' constant-expression
18184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::colon)) {
18194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
18200e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      BitfieldSize = ParseConstantExpression();
18210e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      if (BitfieldSize.isInvalid())
18224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        SkipUntil(tok::comma, true, true);
18234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
18241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1825e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    // If a simple-asm-expr is present, parse it.
1826e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    if (Tok.is(tok::kw_asm)) {
1827e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      SourceLocation Loc;
182860d7b3a319d84d688752be3870615ac0f111fb16John McCall      ExprResult AsmLabel(ParseSimpleAsm(&Loc));
1829e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      if (AsmLabel.isInvalid())
1830e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner        SkipUntil(tok::comma, true, true);
1831e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner
1832e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      DeclaratorInfo.setAsmLabel(AsmLabel.release());
1833e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      DeclaratorInfo.SetRangeEnd(Loc);
1834e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    }
1835e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner
18364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If attributes exist after the declarator, parse them.
1837eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
18384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
18397a614d8380297fcd2bc23986241905d97222948cRichard Smith    // FIXME: When g++ adds support for this, we'll need to check whether it
18407a614d8380297fcd2bc23986241905d97222948cRichard Smith    // goes before or after the GNU attributes and __asm__.
18417a614d8380297fcd2bc23986241905d97222948cRichard Smith    ParseOptionalCXX0XVirtSpecifierSeq(VS);
18427a614d8380297fcd2bc23986241905d97222948cRichard Smith
18437a614d8380297fcd2bc23986241905d97222948cRichard Smith    bool HasDeferredInitializer = false;
18447a614d8380297fcd2bc23986241905d97222948cRichard Smith    if (Tok.is(tok::equal) || Tok.is(tok::l_brace)) {
18457a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (BitfieldSize.get()) {
18467a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(Tok, diag::err_bitfield_member_init);
18477a614d8380297fcd2bc23986241905d97222948cRichard Smith        SkipUntil(tok::comma, true, true);
18487a614d8380297fcd2bc23986241905d97222948cRichard Smith      } else {
1849555f57e3549fb5cc963a2ce38180c4f3643a6f95Douglas Gregor        HasDeferredInitializer = !DeclaratorInfo.isDeclarationOfFunction() &&
18507a614d8380297fcd2bc23986241905d97222948cRichard Smith          DeclaratorInfo.getDeclSpec().getStorageClassSpec()
1851c2cdd5354aba8d6a74c45231829f3bbbbfeb2781Richard Smith            != DeclSpec::SCS_static &&
1852c2cdd5354aba8d6a74c45231829f3bbbbfeb2781Richard Smith          DeclaratorInfo.getDeclSpec().getStorageClassSpec()
1853c2cdd5354aba8d6a74c45231829f3bbbbfeb2781Richard Smith            != DeclSpec::SCS_typedef;
18547a614d8380297fcd2bc23986241905d97222948cRichard Smith
18557a614d8380297fcd2bc23986241905d97222948cRichard Smith        if (!HasDeferredInitializer) {
18567a614d8380297fcd2bc23986241905d97222948cRichard Smith          SourceLocation EqualLoc;
18577a614d8380297fcd2bc23986241905d97222948cRichard Smith          Init = ParseCXXMemberInitializer(
1858555f57e3549fb5cc963a2ce38180c4f3643a6f95Douglas Gregor            DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
18597a614d8380297fcd2bc23986241905d97222948cRichard Smith          if (Init.isInvalid())
18607a614d8380297fcd2bc23986241905d97222948cRichard Smith            SkipUntil(tok::comma, true, true);
18617a614d8380297fcd2bc23986241905d97222948cRichard Smith        }
18627a614d8380297fcd2bc23986241905d97222948cRichard Smith      }
18637a614d8380297fcd2bc23986241905d97222948cRichard Smith    }
18647a614d8380297fcd2bc23986241905d97222948cRichard Smith
186507952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // NOTE: If Sema is the Action module and declarator is an instance field,
1866682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    // this call will *not* return the created decl; It will return null.
186707952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // See Sema::ActOnCXXMemberDeclarator for details.
186867d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall
1869d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decl *ThisDecl = 0;
187067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    if (DS.isFriendSpecified()) {
1871bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall      // TODO: handle initializers, bitfields, 'delete'
187223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo,
1873bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall                                                 /*IsDefinition*/ false,
1874bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall                                                 move(TemplateParams));
187537b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    } else {
187623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS,
187767d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  DeclaratorInfo,
187837b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor                                                  move(TemplateParams),
187967d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  BitfieldSize.release(),
18807a614d8380297fcd2bc23986241905d97222948cRichard Smith                                                  VS, Init.release(),
18817a614d8380297fcd2bc23986241905d97222948cRichard Smith                                                  HasDeferredInitializer,
18827a614d8380297fcd2bc23986241905d97222948cRichard Smith                                                  /*IsDefinition*/ false);
188337b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    }
1884682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    if (ThisDecl)
1885682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      DeclsInGroup.push_back(ThisDecl);
18864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
188772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    if (DeclaratorInfo.isFunctionDeclarator() &&
18881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        DeclaratorInfo.getDeclSpec().getStorageClassSpec()
188972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor          != DeclSpec::SCS_typedef) {
1890d33133cdc1af466f9c276249b2621be03867888bEli Friedman      HandleMemberFunctionDefaultArgs(DeclaratorInfo, ThisDecl);
189172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    }
189272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor
189354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    DeclaratorInfo.complete(ThisDecl);
189454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
1895eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    // Set the Decl for any late parsed attributes
1896eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
1897eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      LateParsedAttrs[i]->setDecl(ThisDecl);
1898eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    }
1899eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    LateParsedAttrs.clear();
1900eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
19017a614d8380297fcd2bc23986241905d97222948cRichard Smith    if (HasDeferredInitializer) {
19027a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (!getLang().CPlusPlus0x)
19037a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(Tok, diag::warn_nonstatic_member_init_accepted_as_extension);
19047a614d8380297fcd2bc23986241905d97222948cRichard Smith
19057a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (DeclaratorInfo.isArrayOfUnknownBound()) {
19067a614d8380297fcd2bc23986241905d97222948cRichard Smith        // C++0x [dcl.array]p3: An array bound may also be omitted when the
19077a614d8380297fcd2bc23986241905d97222948cRichard Smith        // declarator is followed by an initializer.
19087a614d8380297fcd2bc23986241905d97222948cRichard Smith        //
19097a614d8380297fcd2bc23986241905d97222948cRichard Smith        // A brace-or-equal-initializer for a member-declarator is not an
19107a614d8380297fcd2bc23986241905d97222948cRichard Smith        // initializer in the gramamr, so this is ill-formed.
19117a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(Tok, diag::err_incomplete_array_member_init);
19127a614d8380297fcd2bc23986241905d97222948cRichard Smith        SkipUntil(tok::comma, true, true);
19137a614d8380297fcd2bc23986241905d97222948cRichard Smith        // Avoid later warnings about a class member of incomplete type.
19147a614d8380297fcd2bc23986241905d97222948cRichard Smith        ThisDecl->setInvalidDecl();
19157a614d8380297fcd2bc23986241905d97222948cRichard Smith      } else
19167a614d8380297fcd2bc23986241905d97222948cRichard Smith        ParseCXXNonStaticMemberInitializer(ThisDecl);
19177a614d8380297fcd2bc23986241905d97222948cRichard Smith    }
19187a614d8380297fcd2bc23986241905d97222948cRichard Smith
19194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If we don't have a comma, it is either the end of the list (a ';')
19204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // or an error, bail out.
19214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.isNot(tok::comma))
19224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
19231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Consume the comma.
19254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
19261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Parse the next declarator.
19284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    DeclaratorInfo.clear();
19294867347e82648d3baf09524b98b09c297a5a198fNico Weber    VS.clear();
193015faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl    BitfieldSize = 0;
193115faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl    Init = 0;
19321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Attributes are only allowed on the second declarator.
19347f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseGNUAttributes(DeclaratorInfo);
19354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
19363a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    if (Tok.isNot(tok::colon))
19373a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      ParseDeclarator(DeclaratorInfo);
19384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
19394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1940ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner  if (ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
1941ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    // Skip to end of block or statement.
1942ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    SkipUntil(tok::r_brace, true, true);
1943ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    // If we stopped at a ';', eat it.
1944ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    if (Tok.is(tok::semi)) ConsumeToken();
1945682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
19464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
19474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
194823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup.data(),
1949ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner                                  DeclsInGroup.size());
19504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
19514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
19527a614d8380297fcd2bc23986241905d97222948cRichard Smith/// ParseCXXMemberInitializer - Parse the brace-or-equal-initializer or
19537a614d8380297fcd2bc23986241905d97222948cRichard Smith/// pure-specifier. Also detect and reject any attempted defaulted/deleted
19547a614d8380297fcd2bc23986241905d97222948cRichard Smith/// function definition. The location of the '=', if any, will be placed in
19557a614d8380297fcd2bc23986241905d97222948cRichard Smith/// EqualLoc.
19567a614d8380297fcd2bc23986241905d97222948cRichard Smith///
19577a614d8380297fcd2bc23986241905d97222948cRichard Smith///   pure-specifier:
19587a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '= 0'
19597a614d8380297fcd2bc23986241905d97222948cRichard Smith///
19607a614d8380297fcd2bc23986241905d97222948cRichard Smith///   brace-or-equal-initializer:
19617a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '=' initializer-expression
19627a614d8380297fcd2bc23986241905d97222948cRichard Smith///     braced-init-list                       [TODO]
19637a614d8380297fcd2bc23986241905d97222948cRichard Smith///
19647a614d8380297fcd2bc23986241905d97222948cRichard Smith///   initializer-clause:
19657a614d8380297fcd2bc23986241905d97222948cRichard Smith///     assignment-expression
19667a614d8380297fcd2bc23986241905d97222948cRichard Smith///     braced-init-list                       [TODO]
19677a614d8380297fcd2bc23986241905d97222948cRichard Smith///
19687a614d8380297fcd2bc23986241905d97222948cRichard Smith///   defaulted/deleted function-definition:
19697a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '=' 'default'
19707a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '=' 'delete'
19717a614d8380297fcd2bc23986241905d97222948cRichard Smith///
19727a614d8380297fcd2bc23986241905d97222948cRichard Smith/// Prior to C++0x, the assignment-expression in an initializer-clause must
19737a614d8380297fcd2bc23986241905d97222948cRichard Smith/// be a constant-expression.
19747a614d8380297fcd2bc23986241905d97222948cRichard SmithExprResult Parser::ParseCXXMemberInitializer(bool IsFunction,
19757a614d8380297fcd2bc23986241905d97222948cRichard Smith                                             SourceLocation &EqualLoc) {
19767a614d8380297fcd2bc23986241905d97222948cRichard Smith  assert((Tok.is(tok::equal) || Tok.is(tok::l_brace))
19777a614d8380297fcd2bc23986241905d97222948cRichard Smith         && "Data member initializer not starting with '=' or '{'");
19787a614d8380297fcd2bc23986241905d97222948cRichard Smith
19797a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (Tok.is(tok::equal)) {
19807a614d8380297fcd2bc23986241905d97222948cRichard Smith    EqualLoc = ConsumeToken();
19817a614d8380297fcd2bc23986241905d97222948cRichard Smith    if (Tok.is(tok::kw_delete)) {
19827a614d8380297fcd2bc23986241905d97222948cRichard Smith      // In principle, an initializer of '= delete p;' is legal, but it will
19837a614d8380297fcd2bc23986241905d97222948cRichard Smith      // never type-check. It's better to diagnose it as an ill-formed expression
19847a614d8380297fcd2bc23986241905d97222948cRichard Smith      // than as an ill-formed deleted non-function member.
19857a614d8380297fcd2bc23986241905d97222948cRichard Smith      // An initializer of '= delete p, foo' will never be parsed, because
19867a614d8380297fcd2bc23986241905d97222948cRichard Smith      // a top-level comma always ends the initializer expression.
19877a614d8380297fcd2bc23986241905d97222948cRichard Smith      const Token &Next = NextToken();
19887a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (IsFunction || Next.is(tok::semi) || Next.is(tok::comma) ||
19897a614d8380297fcd2bc23986241905d97222948cRichard Smith           Next.is(tok::eof)) {
19907a614d8380297fcd2bc23986241905d97222948cRichard Smith        if (IsFunction)
19917a614d8380297fcd2bc23986241905d97222948cRichard Smith          Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
19927a614d8380297fcd2bc23986241905d97222948cRichard Smith            << 1 /* delete */;
19937a614d8380297fcd2bc23986241905d97222948cRichard Smith        else
19947a614d8380297fcd2bc23986241905d97222948cRichard Smith          Diag(ConsumeToken(), diag::err_deleted_non_function);
19957a614d8380297fcd2bc23986241905d97222948cRichard Smith        return ExprResult();
19967a614d8380297fcd2bc23986241905d97222948cRichard Smith      }
19977a614d8380297fcd2bc23986241905d97222948cRichard Smith    } else if (Tok.is(tok::kw_default)) {
19987a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (IsFunction)
19997a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(Tok, diag::err_default_delete_in_multiple_declaration)
20007a614d8380297fcd2bc23986241905d97222948cRichard Smith          << 0 /* default */;
20017a614d8380297fcd2bc23986241905d97222948cRichard Smith      else
20027a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(ConsumeToken(), diag::err_default_special_members);
20037a614d8380297fcd2bc23986241905d97222948cRichard Smith      return ExprResult();
20047a614d8380297fcd2bc23986241905d97222948cRichard Smith    }
20057a614d8380297fcd2bc23986241905d97222948cRichard Smith
20067a614d8380297fcd2bc23986241905d97222948cRichard Smith    return ParseInitializer();
20077a614d8380297fcd2bc23986241905d97222948cRichard Smith  } else
20087a614d8380297fcd2bc23986241905d97222948cRichard Smith    return ExprError(Diag(Tok, diag::err_generalized_initializer_lists));
20097a614d8380297fcd2bc23986241905d97222948cRichard Smith}
20107a614d8380297fcd2bc23986241905d97222948cRichard Smith
20114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition.
20124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
20134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-specification:
20144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declaration member-specification[opt]
20154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         access-specifier ':' member-specification[opt]
20164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
20174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidisvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
2018d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall                                         unsigned TagType, Decl *TagDecl) {
201931fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta  assert((TagType == DeclSpec::TST_struct ||
20204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis         TagType == DeclSpec::TST_union  ||
202131fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta         TagType == DeclSpec::TST_class) && "Invalid TagType!");
20224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
2023f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
2024f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing struct/union/class body");
20251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
202626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  // Determine whether this is a non-nested class. Note that local
202726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  // classes are *not* considered to be nested classes.
202826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  bool NonNestedClass = true;
202926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  if (!ClassStack.empty()) {
203023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    for (const Scope *S = getCurScope(); S; S = S->getParent()) {
203126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      if (S->isClassScope()) {
203226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // We're inside a class scope, so this is a nested class.
203326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        NonNestedClass = false;
203426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        break;
203526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      }
203626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor
203726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      if ((S->getFlags() & Scope::FnScope)) {
203826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // If we're in a function or function template declared in the
203926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // body of a class, then this is a local class rather than a
204026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // nested class.
204126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        const Scope *Parent = S->getParent();
204226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        if (Parent->isTemplateParamScope())
204326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor          Parent = Parent->getParent();
204426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        if (Parent->isClassScope())
204526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor          break;
204626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      }
204726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor    }
204826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  }
20494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
20504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Enter a scope for the class.
20513218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
20524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
20536569d68745c8213709740337d2be52b031384f58Douglas Gregor  // Note that we are parsing a new (potentially-nested) class definition.
205426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass);
20556569d68745c8213709740337d2be52b031384f58Douglas Gregor
2056ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  if (TagDecl)
205723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
2058bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
2059b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  SourceLocation FinalLoc;
2060b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson
2061b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  // Parse the optional 'final' keyword.
2062b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  if (getLang().CPlusPlus && Tok.is(tok::identifier)) {
2063b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson    IdentifierInfo *II = Tok.getIdentifierInfo();
2064b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson
2065b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson    // Initialize the contextual keywords.
2066b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson    if (!Ident_final) {
2067b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson      Ident_final = &PP.getIdentifierTable().get("final");
2068b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson      Ident_override = &PP.getIdentifierTable().get("override");
2069b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson    }
2070b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson
2071b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson    if (II == Ident_final)
2072b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson      FinalLoc = ConsumeToken();
2073b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson
2074b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson    if (!getLang().CPlusPlus0x)
2075b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson      Diag(FinalLoc, diag::ext_override_control_keyword) << "final";
2076b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  }
2077cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
2078bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  if (Tok.is(tok::colon)) {
2079bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    ParseBaseClause(TagDecl);
2080bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
2081bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    if (!Tok.is(tok::l_brace)) {
2082bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall      Diag(Tok, diag::err_expected_lbrace_after_base_specifiers);
2083db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall
2084db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall      if (TagDecl)
208523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);
2086bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall      return;
2087bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    }
2088bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  }
2089bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
2090bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  assert(Tok.is(tok::l_brace));
2091bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
2092bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  SourceLocation LBraceLoc = ConsumeBrace();
2093bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
209442a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
20952c3ee54e51d835a35bbf781c69e17f39e2ba0480Anders Carlsson    Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc,
2096dfc2f1035d23e294b298766a3cf51dfe249d53a2Anders Carlsson                                            LBraceLoc);
2097f9368159334ff86ea5fa367225c1a580977f3b03John McCall
20984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // C++ 11p3: Members of a class defined with the keyword class are private
20994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // by default. Members of a class defined with the keywords struct or union
21004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // are public by default.
21014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  AccessSpecifier CurAS;
21024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (TagType == DeclSpec::TST_class)
21034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_private;
21044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  else
21054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_public;
21064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
210707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  SourceLocation RBraceLoc;
210807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  if (TagDecl) {
210907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    // While we still have something to read, read the member-declarations.
211007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
211107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Each iteration of this loop reads one member-declaration.
211207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor
2113563a645de82231a55e221fe655b7188bf8369662Francois Pichet      if (getLang().Microsoft && (Tok.is(tok::kw___if_exists) ||
2114563a645de82231a55e221fe655b7188bf8369662Francois Pichet          Tok.is(tok::kw___if_not_exists))) {
2115563a645de82231a55e221fe655b7188bf8369662Francois Pichet        ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
2116563a645de82231a55e221fe655b7188bf8369662Francois Pichet        continue;
2117563a645de82231a55e221fe655b7188bf8369662Francois Pichet      }
2118563a645de82231a55e221fe655b7188bf8369662Francois Pichet
211907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Check for extraneous top-level semicolon.
212007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      if (Tok.is(tok::semi)) {
212107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        Diag(Tok, diag::ext_extra_struct_semi)
212207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor          << DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
212307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor          << FixItHint::CreateRemoval(Tok.getLocation());
212407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        ConsumeToken();
212507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        continue;
212607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      }
21271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
212807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      AccessSpecifier AS = getAccessSpecifierIfPresent();
212907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      if (AS != AS_none) {
213007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        // Current token is a C++ access specifier.
213107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        CurAS = AS;
213207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        SourceLocation ASLoc = Tok.getLocation();
213307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        ConsumeToken();
213407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        if (Tok.is(tok::colon))
213507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor          Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
213607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        else
213707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor          Diag(Tok, diag::err_expected_colon);
213807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        ConsumeToken();
213907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        continue;
214007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      }
21414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
214207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // FIXME: Make sure we don't have a template here.
21434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
214407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Parse all the comma separated declarators.
214507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      ParseCXXClassMemberDeclaration(CurAS);
214607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    }
21471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
214807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
214907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  } else {
215007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    SkipUntil(tok::r_brace, false, false);
21514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
21521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // If attributes exist after class contents, parse them.
21540b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
21557f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseGNUAttributes(attrs);
21564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
215742a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
215823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
215942a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall                                              LBraceLoc, RBraceLoc,
21607f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                              attrs.getList());
21614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
21627a614d8380297fcd2bc23986241905d97222948cRichard Smith  // C++0x [class.mem]p2: Within the class member-specification, the class is
21637a614d8380297fcd2bc23986241905d97222948cRichard Smith  // regarded as complete within function bodies, default arguments, exception-
21647a614d8380297fcd2bc23986241905d97222948cRichard Smith  // specifications, and brace-or-equal-initializers for non-static data
21657a614d8380297fcd2bc23986241905d97222948cRichard Smith  // members (including such things in nested classes).
21664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //
21677a614d8380297fcd2bc23986241905d97222948cRichard Smith  // FIXME: Only function bodies and brace-or-equal-initializers are currently
21687a614d8380297fcd2bc23986241905d97222948cRichard Smith  // handled. Fix the others!
216907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  if (TagDecl && NonNestedClass) {
21704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // We are not inside a nested class. This class and its nested classes
217172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    // are complete and we can parse the delayed portions of method
2172eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    // declarations and the lexed inline method definitions, along with any
2173eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    // delayed attributes.
2174e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor    SourceLocation SavedPrevTokLocation = PrevTokLocation;
2175eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    ParseLexedAttributes(getCurrentClass());
21766569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDeclarations(getCurrentClass());
21777a614d8380297fcd2bc23986241905d97222948cRichard Smith    ParseLexedMemberInitializers(getCurrentClass());
21786569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDefs(getCurrentClass());
2179e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor    PrevTokLocation = SavedPrevTokLocation;
21804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
21814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
218242a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
218323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, RBraceLoc);
2184db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall
21854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Leave the class scope.
21866569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingDef.Pop();
21878935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ClassScope.Exit();
21884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
21897ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
21907ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer,
21917ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a
21927ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers
21937ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below:
21947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
21957ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code
21967ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { };
21977ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base {
21987ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   int x;
21997ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   float f;
22007ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public:
22017ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   Derived(float f) : Base(), x(17), f(f) { }
22027ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// };
22037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode
22047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
22051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  ctor-initializer:
22061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///          ':' mem-initializer-list
22077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
22081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  mem-initializer-list:
22093fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor///          mem-initializer ...[opt]
22103fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor///          mem-initializer ...[opt] , mem-initializer-list
2211d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
22127ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
22137ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
221428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  // Poison the SEH identifiers so they are flagged as illegal in constructor initializers
221528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true);
22167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation ColonLoc = ConsumeToken();
22171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22185f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<CXXCtorInitializer*, 4> MemInitializers;
22199db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  bool AnyErrors = false;
2220193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
22217ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  do {
22220133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    if (Tok.is(tok::code_completion)) {
22230133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      Actions.CodeCompleteConstructorInitializer(ConstructorDecl,
22240133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor                                                 MemInitializers.data(),
22250133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor                                                 MemInitializers.size());
22267d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return cutOffParsing();
22270133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    } else {
22280133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
22290133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      if (!MemInit.isInvalid())
22300133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor        MemInitializers.push_back(MemInit.get());
22310133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      else
22320133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor        AnyErrors = true;
22330133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    }
22340133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor
22357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    if (Tok.is(tok::comma))
22367ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      ConsumeToken();
22377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    else if (Tok.is(tok::l_brace))
22387ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
2239b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor    // If the next token looks like a base or member initializer, assume that
2240b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor    // we're just missing a comma.
2241751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor    else if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) {
2242751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor      SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
2243751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor      Diag(Loc, diag::err_ctor_init_missing_comma)
2244751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor        << FixItHint::CreateInsertion(Loc, ", ");
2245751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor    } else {
22467ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      // Skip over garbage, until we get to '{'.  Don't eat the '{'.
2247d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl      Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
22487ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      SkipUntil(tok::l_brace, true, true);
22497ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
22507ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    }
22517ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  } while (true);
22527ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
22531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc,
22549db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                               MemInitializers.data(), MemInitializers.size(),
22559db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                               AnyErrors);
22567ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
22577ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
22587ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is
22597ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one
22607ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See
22617ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example.
22627ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
22637ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer:
22647ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         mem-initializer-id '(' expression-list[opt] ')'
2265dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// [C++0x] mem-initializer-id braced-init-list
22661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
22677ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id:
22687ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         '::'[opt] nested-name-specifier[opt] class-name
22697ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         identifier
2270d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
2271bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  // parse '::'[opt] nested-name-specifier[opt]
2272bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  CXXScopeSpec SS;
2273b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
2274b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TemplateTypeTy;
2275961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (Tok.is(tok::annot_template_id)) {
227625a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
2277d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor    if (TemplateId->Kind == TNK_Type_template ||
2278d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor        TemplateId->Kind == TNK_Dependent_template_name) {
2279059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
2280961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
2281b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      TemplateTypeTy = getTypeAnnotation(Tok);
2282961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    }
2283961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  }
2284961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (!TemplateTypeTy && Tok.isNot(tok::identifier)) {
22851ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_member_or_base_name);
22867ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
22877ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
22881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22897ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Get the identifier. This may be a member name or a class name,
22907ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // but we'll let the semantic analysis determine which it is.
2291961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  IdentifierInfo *II = Tok.is(tok::identifier) ? Tok.getIdentifierInfo() : 0;
22927ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation IdLoc = ConsumeToken();
22937ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
22947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Parse the '('.
2295dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl  if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
2296dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    // FIXME: Do something with the braced-init-list.
2297dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    ParseBraceInitializer();
22987ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
2299dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl  } else if(Tok.is(tok::l_paren)) {
2300dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    SourceLocation LParenLoc = ConsumeParen();
2301dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl
2302dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    // Parse the optional expression-list.
2303dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    ExprVector ArgExprs(Actions);
2304dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    CommaLocsTy CommaLocs;
2305dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
2306dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl      SkipUntil(tok::r_paren);
2307dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl      return true;
2308dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    }
23097ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
2310dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
23117ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
2312dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    SourceLocation EllipsisLoc;
2313dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    if (Tok.is(tok::ellipsis))
2314dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl      EllipsisLoc = ConsumeToken();
23157ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
2316dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
2317dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl                                       TemplateTypeTy, IdLoc,
2318dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl                                       LParenLoc, ArgExprs.take(),
2319dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl                                       ArgExprs.size(), RParenLoc,
2320dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl                                       EllipsisLoc);
2321dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl  }
2322dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl
2323dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl  Diag(Tok, getLang().CPlusPlus0x ? diag::err_expected_lparen_or_lbrace
2324dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl                                  : diag::err_expected_lparen);
2325dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl  return true;
23267ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
23270fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
23287acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// \brief Parse a C++ exception-specification if present (C++0x [except.spec]).
23290fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
2330a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       exception-specification:
23317acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         dynamic-exception-specification
23327acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         noexcept-specification
23337acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///
23347acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///       noexcept-specification:
23357acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         'noexcept'
23367acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         'noexcept' '(' constant-expression ')'
23377acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType
23387acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlParser::MaybeParseExceptionSpecification(SourceRange &SpecificationRange,
23395f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                    SmallVectorImpl<ParsedType> &DynamicExceptions,
23405f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                    SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
23417acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                    ExprResult &NoexceptExpr) {
23427acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  ExceptionSpecificationType Result = EST_None;
23437acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
23447acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // See if there's a dynamic specification.
23457acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.is(tok::kw_throw)) {
23467acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Result = ParseDynamicExceptionSpecification(SpecificationRange,
23477acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                                DynamicExceptions,
23487acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                                DynamicExceptionRanges);
23497acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    assert(DynamicExceptions.size() == DynamicExceptionRanges.size() &&
23507acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl           "Produced different number of exception types and ranges.");
23517acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
23527acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
23537acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // If there's no noexcept specification, we're done.
23547acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.isNot(tok::kw_noexcept))
23557acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    return Result;
23567acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
23577acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // If we already had a dynamic specification, parse the noexcept for,
23587acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // recovery, but emit a diagnostic and don't store the results.
23597acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SourceRange NoexceptRange;
23607acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  ExceptionSpecificationType NoexceptType = EST_None;
23617acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
23627acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SourceLocation KeywordLoc = ConsumeToken();
23637acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.is(tok::l_paren)) {
23647acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // There is an argument.
23657acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SourceLocation LParenLoc = ConsumeParen();
23667acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptType = EST_ComputedNoexcept;
23677acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptExpr = ParseConstantExpression();
236860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    // The argument must be contextually convertible to bool. We use
236960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    // ActOnBooleanCondition for this purpose.
237060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    if (!NoexceptExpr.isInvalid())
237160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl      NoexceptExpr = Actions.ActOnBooleanCondition(getCurScope(), KeywordLoc,
237260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl                                                   NoexceptExpr.get());
23737acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
23747acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptRange = SourceRange(KeywordLoc, RParenLoc);
23757acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  } else {
23767acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // There is no argument.
23777acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptType = EST_BasicNoexcept;
23787acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptRange = SourceRange(KeywordLoc, KeywordLoc);
23797acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
23807acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
23817acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Result == EST_None) {
23827acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SpecificationRange = NoexceptRange;
23837acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Result = NoexceptType;
23847acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
23857acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // If there's a dynamic specification after a noexcept specification,
23867acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // parse that and ignore the results.
23877acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    if (Tok.is(tok::kw_throw)) {
23887acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
23897acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions,
23907acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                         DynamicExceptionRanges);
23917acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    }
23927acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  } else {
23937acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
23947acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
23957acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
23967acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  return Result;
23977acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl}
23987acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
23997acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// ParseDynamicExceptionSpecification - Parse a C++
24007acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification (C++ [except.spec]).
24017acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///
24027acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///       dynamic-exception-specification:
2403a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         'throw' '(' type-id-list [opt] ')'
2404a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS]    'throw' '(' '...' ')'
24051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
2406a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       type-id-list:
2407a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor///         type-id ... [opt]
2408a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor///         type-id-list ',' type-id ... [opt]
24090fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
24107acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(
24117acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                  SourceRange &SpecificationRange,
24125f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                  SmallVectorImpl<ParsedType> &Exceptions,
24135f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                  SmallVectorImpl<SourceRange> &Ranges) {
24140fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  assert(Tok.is(tok::kw_throw) && "expected throw");
24151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24167acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SpecificationRange.setBegin(ConsumeToken());
24171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24180fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  if (!Tok.is(tok::l_paren)) {
24197acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Diag(Tok, diag::err_expected_lparen_after) << "throw";
24207acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SpecificationRange.setEnd(SpecificationRange.getBegin());
242160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    return EST_DynamicNone;
24220fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
24230fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  SourceLocation LParenLoc = ConsumeParen();
24240fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
2425a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // Parse throw(...), a Microsoft extension that means "this function
2426a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // can throw anything".
2427a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  if (Tok.is(tok::ellipsis)) {
2428a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    SourceLocation EllipsisLoc = ConsumeToken();
2429a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    if (!getLang().Microsoft)
2430a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor      Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
24317acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
24327acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SpecificationRange.setEnd(RParenLoc);
243360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    return EST_MSAny;
2434a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  }
2435a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor
24360fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  // Parse the sequence of type-ids.
2437ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl  SourceRange Range;
24380fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  while (Tok.isNot(tok::r_paren)) {
2439ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    TypeResult Res(ParseTypeName(&Range));
24407acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
2441a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor    if (Tok.is(tok::ellipsis)) {
2442a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      // C++0x [temp.variadic]p5:
2443a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      //   - In a dynamic-exception-specification (15.4); the pattern is a
2444a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      //     type-id.
2445a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      SourceLocation Ellipsis = ConsumeToken();
24467acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      Range.setEnd(Ellipsis);
2447a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      if (!Res.isInvalid())
2448a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor        Res = Actions.ActOnPackExpansion(Res.get(), Ellipsis);
2449a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor    }
24507acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
2451ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    if (!Res.isInvalid()) {
24527dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl      Exceptions.push_back(Res.get());
2453ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl      Ranges.push_back(Range);
2454ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    }
2455a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor
24560fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor    if (Tok.is(tok::comma))
24570fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      ConsumeToken();
24587dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl    else
24590fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      break;
24600fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
24610fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
24627acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SpecificationRange.setEnd(MatchRHSPunctuation(tok::r_paren, LParenLoc));
246360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl  return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic;
24640fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor}
24656569d68745c8213709740337d2be52b031384f58Douglas Gregor
2466dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// ParseTrailingReturnType - Parse a trailing return type on a new-style
2467dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// function declaration.
2468ae7902c4293d9de8b9591759513f0d075f45022aDouglas GregorTypeResult Parser::ParseTrailingReturnType(SourceRange &Range) {
2469dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  assert(Tok.is(tok::arrow) && "expected arrow");
2470dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
2471dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  ConsumeToken();
2472dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
2473dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  // FIXME: Need to suppress declarations when parsing this typename.
2474dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  // Otherwise in this function definition:
2475dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  //
2476dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  //   auto f() -> struct X {}
2477dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  //
2478dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  // struct X is parsed as class definition because of the trailing
2479dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  // brace.
2480dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  return ParseTypeName(&Range);
2481dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor}
2482dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
24836569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief We have just started parsing the definition of a new class,
24846569d68745c8213709740337d2be52b031384f58Douglas Gregor/// so push that class onto our stack of classes that is currently
24856569d68745c8213709740337d2be52b031384f58Douglas Gregor/// being parsed.
2486eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallSema::ParsingClassState
2487eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallParser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass) {
248826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  assert((NonNestedClass || !ClassStack.empty()) &&
24896569d68745c8213709740337d2be52b031384f58Douglas Gregor         "Nested class without outer class");
249026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass));
2491eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  return Actions.PushParsingClass();
24926569d68745c8213709740337d2be52b031384f58Douglas Gregor}
24936569d68745c8213709740337d2be52b031384f58Douglas Gregor
24946569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Deallocate the given parsed class and all of its nested
24956569d68745c8213709740337d2be52b031384f58Douglas Gregor/// classes.
24966569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
2497d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I)
2498d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    delete Class->LateParsedDeclarations[I];
24996569d68745c8213709740337d2be52b031384f58Douglas Gregor  delete Class;
25006569d68745c8213709740337d2be52b031384f58Douglas Gregor}
25016569d68745c8213709740337d2be52b031384f58Douglas Gregor
25026569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Pop the top class of the stack of classes that are
25036569d68745c8213709740337d2be52b031384f58Douglas Gregor/// currently being parsed.
25046569d68745c8213709740337d2be52b031384f58Douglas Gregor///
25056569d68745c8213709740337d2be52b031384f58Douglas Gregor/// This routine should be called when we have finished parsing the
25066569d68745c8213709740337d2be52b031384f58Douglas Gregor/// definition of a class, but have not yet popped the Scope
25076569d68745c8213709740337d2be52b031384f58Douglas Gregor/// associated with the class's definition.
25086569d68745c8213709740337d2be52b031384f58Douglas Gregor///
25096569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \returns true if the class we've popped is a top-level class,
25106569d68745c8213709740337d2be52b031384f58Douglas Gregor/// false otherwise.
2511eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Parser::PopParsingClass(Sema::ParsingClassState state) {
25126569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");
25131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2514eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  Actions.PopParsingClass(state);
2515eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
25166569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingClass *Victim = ClassStack.top();
25176569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.pop();
25186569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (Victim->TopLevelClass) {
25196569d68745c8213709740337d2be52b031384f58Douglas Gregor    // Deallocate all of the nested classes of this class,
25206569d68745c8213709740337d2be52b031384f58Douglas Gregor    // recursively: we don't need to keep any of this information.
25216569d68745c8213709740337d2be52b031384f58Douglas Gregor    DeallocateParsedClasses(Victim);
25226569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
25231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
25246569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Missing top-level class?");
25256569d68745c8213709740337d2be52b031384f58Douglas Gregor
2526d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (Victim->LateParsedDeclarations.empty()) {
25276569d68745c8213709740337d2be52b031384f58Douglas Gregor    // The victim is a nested class, but we will not need to perform
25286569d68745c8213709740337d2be52b031384f58Douglas Gregor    // any processing after the definition of this class since it has
25296569d68745c8213709740337d2be52b031384f58Douglas Gregor    // no members whose handling was delayed. Therefore, we can just
25306569d68745c8213709740337d2be52b031384f58Douglas Gregor    // remove this nested class.
2531d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    DeallocateParsedClasses(Victim);
25326569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
25336569d68745c8213709740337d2be52b031384f58Douglas Gregor  }
25346569d68745c8213709740337d2be52b031384f58Douglas Gregor
25356569d68745c8213709740337d2be52b031384f58Douglas Gregor  // This nested class has some members that will need to be processed
25366569d68745c8213709740337d2be52b031384f58Douglas Gregor  // after the top-level class is completely defined. Therefore, add
25376569d68745c8213709740337d2be52b031384f58Douglas Gregor  // it to the list of nested classes within its parent.
253823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  assert(getCurScope()->isClassScope() && "Nested class outside of class scope?");
2539d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ClassStack.top()->LateParsedDeclarations.push_back(new LateParsedClass(this, Victim));
254023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope();
25416569d68745c8213709740337d2be52b031384f58Douglas Gregor}
2542bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2543bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// ParseCXX0XAttributes - Parse a C++0x attribute-specifier. Currently only
2544bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// parses standard attributes.
2545bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2546bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-specifier:
2547bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' '[' attribute-list ']' ']'
2548bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2549bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-list:
2550bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute[opt]
2551bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-list ',' attribute[opt]
2552bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2553bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute:
2554bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-token attribute-argument-clause[opt]
2555bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2556bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-token:
2557bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
2558bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-scoped-token
2559bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2560bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-scoped-token:
2561bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-namespace '::' identifier
2562bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2563bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-namespace:
2564bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
2565bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2566bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-argument-clause:
2567bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
2568bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2569bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] balanced-token-seq:
2570bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token
2571bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token-seq balanced-token
2572bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2573bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] balanced-token:
2574bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
2575bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' balanced-token-seq ']'
2576bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '{' balanced-token-seq '}'
2577bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         any token but '(', ')', '[', ']', '{', or '}'
25787f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCallvoid Parser::ParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
25797f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                  SourceLocation *endLoc) {
2580bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
2581bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      && "Not a C++0x attribute list");
2582bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2583bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  SourceLocation StartLoc = Tok.getLocation(), Loc;
2584bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2585bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
2586bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
2587193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
2588bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Tok.is(tok::comma)) {
2589bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Diag(Tok.getLocation(), diag::err_expected_ident);
2590bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    ConsumeToken();
2591bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
2592bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2593bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  while (Tok.is(tok::identifier) || Tok.is(tok::comma)) {
2594bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // attribute not present
2595bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::comma)) {
2596bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
2597bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      continue;
2598bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2599bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2600bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    IdentifierInfo *ScopeName = 0, *AttrName = Tok.getIdentifierInfo();
2601bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceLocation ScopeLoc, AttrLoc = ConsumeToken();
2602193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
2603bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // scoped attribute
2604bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::coloncolon)) {
2605bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
2606bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2607bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      if (!Tok.is(tok::identifier)) {
2608bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        Diag(Tok.getLocation(), diag::err_expected_ident);
2609bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        SkipUntil(tok::r_square, tok::comma, true, true);
2610bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        continue;
2611bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2612193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
2613bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ScopeName = AttrName;
2614bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ScopeLoc = AttrLoc;
2615bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2616bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttrName = Tok.getIdentifierInfo();
2617bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttrLoc = ConsumeToken();
2618bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2619bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2620bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    bool AttrParsed = false;
2621bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // No scoped names are supported; ideally we could put all non-standard
2622bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // attributes into namespaces.
2623bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (!ScopeName) {
2624bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      switch(AttributeList::getKind(AttrName))
2625bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      {
2626bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // No arguments
26277725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_carries_dependency:
262815e14a289583616e582a23b320933e846a742626Anders Carlsson      case AttributeList::AT_noreturn: {
2629bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        if (Tok.is(tok::l_paren)) {
2630bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          Diag(Tok.getLocation(), diag::err_cxx0x_attribute_forbids_arguments)
2631bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt            << AttrName->getName();
2632bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          break;
2633bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        }
2634bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
26350b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall        attrs.addNew(AttrName, AttrLoc, 0, AttrLoc, 0,
26360b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                     SourceLocation(), 0, 0, false, true);
2637bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        AttrParsed = true;
2638bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        break;
2639bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2640bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2641bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // One argument; must be a type-id or assignment-expression
2642bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      case AttributeList::AT_aligned: {
2643bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        if (Tok.isNot(tok::l_paren)) {
2644bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          Diag(Tok.getLocation(), diag::err_cxx0x_attribute_requires_arguments)
2645bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt            << AttrName->getName();
2646bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          break;
2647bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        }
2648bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        SourceLocation ParamLoc = ConsumeParen();
2649bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
265060d7b3a319d84d688752be3870615ac0f111fb16John McCall        ExprResult ArgExpr = ParseCXX0XAlignArgument(ParamLoc);
2651bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2652bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        MatchRHSPunctuation(tok::r_paren, ParamLoc);
2653bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2654bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        ExprVector ArgExprs(Actions);
2655bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        ArgExprs.push_back(ArgExpr.release());
26560b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall        attrs.addNew(AttrName, AttrLoc, 0, AttrLoc,
26570b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                     0, ParamLoc, ArgExprs.take(), 1,
26580b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                     false, true);
2659bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2660bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        AttrParsed = true;
2661bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        break;
2662bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2663bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2664bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // Silence warnings
2665bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      default: break;
2666bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2667bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2668bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2669bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // Skip the entire parameter clause, if any
2670bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (!AttrParsed && Tok.is(tok::l_paren)) {
2671bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeParen();
2672bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // SkipUntil maintains the balancedness of tokens.
2673bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      SkipUntil(tok::r_paren, false);
2674bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2675bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
2676bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2677bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
2678bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
2679bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  Loc = Tok.getLocation();
2680bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
2681bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
2682bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
26837f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  attrs.Range = SourceRange(StartLoc, Loc);
2684bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
2685bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2686bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// ParseCXX0XAlignArgument - Parse the argument to C++0x's [[align]]
2687bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute.
2688bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2689bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// FIXME: Simply returns an alignof() expression if the argument is a
2690bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// type. Ideally, the type should be propagated directly into Sema.
2691bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2692bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] 'align' '(' type-id ')'
2693bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] 'align' '(' assignment-expression ')'
269460d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) {
2695bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (isTypeIdInParens()) {
2696f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
2697bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceLocation TypeLoc = Tok.getLocation();
2698b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    ParsedType Ty = ParseTypeName().get();
2699bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceRange TypeRange(Start, Tok.getLocation());
2700f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne    return Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true,
2701f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne                                                Ty.getAsOpaquePtr(), TypeRange);
2702bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  } else
2703bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return ParseConstantExpression();
2704bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
2705334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet
2706334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ParseMicrosoftAttributes - Parse a Microsoft attribute [Attr]
2707334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///
2708334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute:
2709334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             '[' token-seq ']'
2710334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///
2711334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute-seq:
2712334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             ms-attribute[opt]
2713334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             ms-attribute ms-attribute-seq
27147f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCallvoid Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs,
27157f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                      SourceLocation *endLoc) {
2716334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
2717334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet
2718334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  while (Tok.is(tok::l_square)) {
2719334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    ConsumeBracket();
2720334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    SkipUntil(tok::r_square, true, true);
27217f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    if (endLoc) *endLoc = Tok.getLocation();
2722334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
2723334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  }
2724334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet}
2725563a645de82231a55e221fe655b7188bf8369662Francois Pichet
2726563a645de82231a55e221fe655b7188bf8369662Francois Pichetvoid Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
2727563a645de82231a55e221fe655b7188bf8369662Francois Pichet                                                    AccessSpecifier& CurAS) {
2728563a645de82231a55e221fe655b7188bf8369662Francois Pichet  bool Result;
2729563a645de82231a55e221fe655b7188bf8369662Francois Pichet  if (ParseMicrosoftIfExistsCondition(Result))
2730563a645de82231a55e221fe655b7188bf8369662Francois Pichet    return;
2731563a645de82231a55e221fe655b7188bf8369662Francois Pichet
2732563a645de82231a55e221fe655b7188bf8369662Francois Pichet  if (Tok.isNot(tok::l_brace)) {
2733563a645de82231a55e221fe655b7188bf8369662Francois Pichet    Diag(Tok, diag::err_expected_lbrace);
2734563a645de82231a55e221fe655b7188bf8369662Francois Pichet    return;
2735563a645de82231a55e221fe655b7188bf8369662Francois Pichet  }
2736563a645de82231a55e221fe655b7188bf8369662Francois Pichet  ConsumeBrace();
2737563a645de82231a55e221fe655b7188bf8369662Francois Pichet
2738563a645de82231a55e221fe655b7188bf8369662Francois Pichet  // Condition is false skip all inside the {}.
2739563a645de82231a55e221fe655b7188bf8369662Francois Pichet  if (!Result) {
2740563a645de82231a55e221fe655b7188bf8369662Francois Pichet    SkipUntil(tok::r_brace, false);
2741563a645de82231a55e221fe655b7188bf8369662Francois Pichet    return;
2742563a645de82231a55e221fe655b7188bf8369662Francois Pichet  }
2743563a645de82231a55e221fe655b7188bf8369662Francois Pichet
2744563a645de82231a55e221fe655b7188bf8369662Francois Pichet  // Condition is true, parse the declaration.
2745563a645de82231a55e221fe655b7188bf8369662Francois Pichet  while (Tok.isNot(tok::r_brace)) {
2746563a645de82231a55e221fe655b7188bf8369662Francois Pichet
2747563a645de82231a55e221fe655b7188bf8369662Francois Pichet    // __if_exists, __if_not_exists can nest.
2748563a645de82231a55e221fe655b7188bf8369662Francois Pichet    if ((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists))) {
2749563a645de82231a55e221fe655b7188bf8369662Francois Pichet      ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
2750563a645de82231a55e221fe655b7188bf8369662Francois Pichet      continue;
2751563a645de82231a55e221fe655b7188bf8369662Francois Pichet    }
2752563a645de82231a55e221fe655b7188bf8369662Francois Pichet
2753563a645de82231a55e221fe655b7188bf8369662Francois Pichet    // Check for extraneous top-level semicolon.
2754563a645de82231a55e221fe655b7188bf8369662Francois Pichet    if (Tok.is(tok::semi)) {
2755563a645de82231a55e221fe655b7188bf8369662Francois Pichet      Diag(Tok, diag::ext_extra_struct_semi)
2756563a645de82231a55e221fe655b7188bf8369662Francois Pichet        << DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
2757563a645de82231a55e221fe655b7188bf8369662Francois Pichet        << FixItHint::CreateRemoval(Tok.getLocation());
2758563a645de82231a55e221fe655b7188bf8369662Francois Pichet      ConsumeToken();
2759563a645de82231a55e221fe655b7188bf8369662Francois Pichet      continue;
2760563a645de82231a55e221fe655b7188bf8369662Francois Pichet    }
2761563a645de82231a55e221fe655b7188bf8369662Francois Pichet
2762563a645de82231a55e221fe655b7188bf8369662Francois Pichet    AccessSpecifier AS = getAccessSpecifierIfPresent();
2763563a645de82231a55e221fe655b7188bf8369662Francois Pichet    if (AS != AS_none) {
2764563a645de82231a55e221fe655b7188bf8369662Francois Pichet      // Current token is a C++ access specifier.
2765563a645de82231a55e221fe655b7188bf8369662Francois Pichet      CurAS = AS;
2766563a645de82231a55e221fe655b7188bf8369662Francois Pichet      SourceLocation ASLoc = Tok.getLocation();
2767563a645de82231a55e221fe655b7188bf8369662Francois Pichet      ConsumeToken();
2768563a645de82231a55e221fe655b7188bf8369662Francois Pichet      if (Tok.is(tok::colon))
2769563a645de82231a55e221fe655b7188bf8369662Francois Pichet        Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
2770563a645de82231a55e221fe655b7188bf8369662Francois Pichet      else
2771563a645de82231a55e221fe655b7188bf8369662Francois Pichet        Diag(Tok, diag::err_expected_colon);
2772563a645de82231a55e221fe655b7188bf8369662Francois Pichet      ConsumeToken();
2773563a645de82231a55e221fe655b7188bf8369662Francois Pichet      continue;
2774563a645de82231a55e221fe655b7188bf8369662Francois Pichet    }
2775563a645de82231a55e221fe655b7188bf8369662Francois Pichet
2776563a645de82231a55e221fe655b7188bf8369662Francois Pichet    // Parse all the comma separated declarators.
2777563a645de82231a55e221fe655b7188bf8369662Francois Pichet    ParseCXXClassMemberDeclaration(CurAS);
2778563a645de82231a55e221fe655b7188bf8369662Francois Pichet  }
2779563a645de82231a55e221fe655b7188bf8369662Francois Pichet
2780563a645de82231a55e221fe655b7188bf8369662Francois Pichet  if (Tok.isNot(tok::r_brace)) {
2781563a645de82231a55e221fe655b7188bf8369662Francois Pichet    Diag(Tok, diag::err_expected_rbrace);
2782563a645de82231a55e221fe655b7188bf8369662Francois Pichet    return;
2783563a645de82231a55e221fe655b7188bf8369662Francois Pichet  }
2784563a645de82231a55e221fe655b7188bf8369662Francois Pichet  ConsumeBrace();
2785563a645de82231a55e221fe655b7188bf8369662Francois Pichet}
2786