ParseDeclCXX.cpp revision 0eb7526cd2524af78fb9a2a2522045fb25fc3d27
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"
218fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer#include "llvm/ADT/SmallString.h"
22d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner#include "RAIIObjectsForParser.h"
238f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattnerusing namespace clang;
248f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner
258f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// ParseNamespace - We know that the current token is a namespace keyword. This
26d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// may either be a top level namespace or a block-level namespace alias. If
27d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// there was an inline keyword, it has already been parsed.
288f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
298f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       namespace-definition: [C++ 7.3: basic.namespace]
308f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         named-namespace-definition
318f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         unnamed-namespace-definition
328f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
338f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       unnamed-namespace-definition:
34d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' attributes[opt] '{' namespace-body '}'
358f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
368f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       named-namespace-definition:
378f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         original-namespace-definition
388f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         extension-namespace-definition
398f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
408f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       original-namespace-definition:
41d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' identifier attributes[opt]
42d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///             '{' namespace-body '}'
438f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
448f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       extension-namespace-definition:
45d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' original-namespace-name
46d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///             '{' namespace-body '}'
471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
488f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       namespace-alias-definition:  [C++ 7.3.2: namespace.alias]
498f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         'namespace' identifier '=' qualified-namespace-specifier ';'
508f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
51d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespace(unsigned Context,
52d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl                             SourceLocation &DeclEnd,
53d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl                             SourceLocation InlineLoc) {
5404d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
558f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation NamespaceLoc = ConsumeToken();  // eat the 'namespace'.
569735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian  ObjCDeclContextSwitch ObjCDC(*this);
57a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian
5849f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
5923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteNamespaceDecl(getCurScope());
607d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
617d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
6249f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
63193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
648f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation IdentLoc;
658f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  IdentifierInfo *Ident = 0;
66f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  std::vector<SourceLocation> ExtraIdentLoc;
67f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  std::vector<IdentifierInfo*> ExtraIdent;
68f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  std::vector<SourceLocation> ExtraNamespaceLoc;
696a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
706a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  Token attrTok;
711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7204d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  if (Tok.is(tok::identifier)) {
738f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    Ident = Tok.getIdentifierInfo();
748f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    IdentLoc = ConsumeToken();  // eat the identifier.
75f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    while (Tok.is(tok::coloncolon) && NextToken().is(tok::identifier)) {
76f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ExtraNamespaceLoc.push_back(ConsumeToken());
77f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ExtraIdent.push_back(Tok.getIdentifierInfo());
78f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ExtraIdentLoc.push_back(ConsumeToken());
79f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
808f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  }
811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
828f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  // Read label attributes, if present.
830b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
846a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::kw___attribute)) {
856a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor    attrTok = Tok;
867f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
876a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
896a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::equal)) {
907f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    if (!attrs.empty())
916a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor      Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
92d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl    if (InlineLoc.isValid())
93d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl      Diag(InlineLoc, diag::err_inline_namespace_alias)
94d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl          << FixItHint::CreateRemoval(InlineLoc);
959735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian    return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
966a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
98f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
994a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_brace);
1004a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.consumeOpen()) {
101f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    if (!ExtraIdent.empty()) {
102f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
103f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back());
104f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
1051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Diag(Tok, Ident ? diag::err_expected_lbrace :
1065144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner         diag::err_expected_ident_lbrace);
107d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
1085144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  }
1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
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    }
1174a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    Diag(T.getOpenLocation(), 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.
1527fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith  if (InlineLoc.isValid())
1534e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    Diag(InlineLoc, getLangOpts().CPlusPlus0x ?
1547fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith         diag::warn_cxx98_compat_inline_namespace : diag::ext_inline_namespace);
15588e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl
1565144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Enter a scope for the namespace.
1575144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  ParseScope NamespaceScope(this, Scope::DeclScope);
1582d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
159d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *NamespcDecl =
160acba90f30876b4140b738f0d3dd0e50724053a96Abramo Bagnara    Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, NamespaceLoc,
1614a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                   IdentLoc, Ident, T.getOpenLocation(),
1624a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                   attrs.getList());
1632d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
164f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc,
165f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing namespace");
1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
167f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  // Parse the contents of the namespace.  This includes parsing recovery on
168f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  // any improperly nested namespaces.
169f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  ParseInnerNamespace(ExtraIdentLoc, ExtraIdent, ExtraNamespaceLoc, 0,
1704a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                      InlineLoc, attrs, T);
1711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1725144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Leave the namespace scope.
1735144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  NamespaceScope.Exit();
1748ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis
1754a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  DeclEnd = T.getCloseLocation();
1764a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  Actions.ActOnFinishNamespaceDef(NamespcDecl, DeclEnd);
1772d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
1785144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  return NamespcDecl;
1798f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner}
180c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
181f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu/// ParseInnerNamespace - Parse the contents of a namespace.
182f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieuvoid Parser::ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc,
183f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 std::vector<IdentifierInfo*>& Ident,
184f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 std::vector<SourceLocation>& NamespaceLoc,
185f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 unsigned int index, SourceLocation& InlineLoc,
186f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 ParsedAttributes& attrs,
1874a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                 BalancedDelimiterTracker &Tracker) {
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    }
1954a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor
1964a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    // The caller is what called check -- we are simply calling
1974a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    // the close for it.
1984a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    Tracker.consumeClose();
199f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
200f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    return;
201f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  }
202f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
203f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  // Parse improperly nested namespaces.
204f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  ParseScope NamespaceScope(this, Scope::DeclScope);
205f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  Decl *NamespcDecl =
206f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    Actions.ActOnStartNamespaceDef(getCurScope(), SourceLocation(),
207f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                   NamespaceLoc[index], IdentLoc[index],
2084a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                   Ident[index], Tracker.getOpenLocation(),
2094a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                   attrs.getList());
210f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
211f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  ParseInnerNamespace(IdentLoc, Ident, NamespaceLoc, ++index, InlineLoc,
2124a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                      attrs, Tracker);
213f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
214f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  NamespaceScope.Exit();
215f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
2164a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  Actions.ActOnFinishNamespaceDef(NamespcDecl, Tracker.getCloseLocation());
217f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu}
218f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
219f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
220f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// alias definition.
221f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson///
222d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
2230b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  SourceLocation AliasLoc,
2240b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  IdentifierInfo *Alias,
2250b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  SourceLocation &DeclEnd) {
226f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  assert(Tok.is(tok::equal) && "Not equal token");
2271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
228f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  ConsumeToken(); // eat the '='.
2291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
23123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteNamespaceAliasDecl(getCurScope());
2327d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
2337d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
23449f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
235193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
236f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  CXXScopeSpec SS;
237f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse (optional) nested-name-specifier.
238efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
239f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
240f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
241f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    Diag(Tok, diag::err_expected_namespace_name);
242f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    // Skip to end of the definition and eat the ';'.
243f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    SkipUntil(tok::semi);
244d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
245f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  }
246f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
247f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse identifier.
24803bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  IdentifierInfo *Ident = Tok.getIdentifierInfo();
24903bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  SourceLocation IdentLoc = ConsumeToken();
2501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
251f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Eat the ';'.
25297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
2536869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name,
2546869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner                   "", tok::semi);
2551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
25623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc, Alias,
25703bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson                                        SS, IdentLoc, Ident);
258f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson}
259f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
260c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal
261c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen.
262c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
263c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///       linkage-specification: [C++ 7.5p2: dcl.link]
264c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal '{' declaration-seq[opt] '}'
265c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal declaration
266c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
2677d64271b162eaf5cae264ff64465b28af623dc17Chris LattnerDecl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
268c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor  assert(Tok.is(tok::string_literal) && "Not a string literal!");
269f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<8> LangBuffer;
270453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  bool Invalid = false;
2715f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid);
272453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  if (Invalid)
273d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
274c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
27599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  // FIXME: This is incorrect: linkage-specifiers are parsed in translation
27699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  // phase 7, so string-literal concatenation is supposed to occur.
27799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  //   extern "" "C" "" "+" "+" { } is legal.
27899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  if (Tok.hasUDSuffix())
27999831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    Diag(Tok, diag::err_invalid_string_udl);
280c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  SourceLocation Loc = ConsumeStringToken();
281c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
282074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  ParseScope LinkageScope(this, Scope::DeclScope);
283d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *LinkageSpec
28423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    = Actions.ActOnStartLinkageSpecification(getCurScope(),
285a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                             DS.getSourceRange().getBegin(),
286d56638180014e60538cd666cd11fde6d4698e051Benjamin Kramer                                             Loc, Lang,
287a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                      Tok.is(tok::l_brace) ? Tok.getLocation()
288074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                           : SourceLocation());
289074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
2900b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributesWithRange attrs(AttrFactory);
2917f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseCXX0XAttributes(attrs);
2927f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseMicrosoftAttributes(attrs);
293193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
294074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (Tok.isNot(tok::l_brace)) {
295f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // Reset the source range in DS, as the leading "extern"
296f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // does not really belong to the inner declaration ...
297f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    DS.SetRangeStart(SourceLocation());
298f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    DS.SetRangeEnd(SourceLocation());
299f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // ... but anyway remember that such an "extern" was seen.
30035f9a196ef897b9559de25aaecd957208f0b4f59Abramo Bagnara    DS.setExternInLinkageSpec(true);
3017f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseExternalDeclaration(attrs, &DS);
30223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
303074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                   SourceLocation());
3041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
305f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor
30663a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor  DS.abort();
30763a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor
3087f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  ProhibitAttributes(attrs);
309bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
3104a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_brace);
3114a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
312f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
3130b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    ParsedAttributesWithRange attrs(AttrFactory);
3147f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseCXX0XAttributes(attrs);
3157f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseMicrosoftAttributes(attrs);
3167f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseExternalDeclaration(attrs);
317f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  }
318c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
3194a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
3207d64271b162eaf5cae264ff64465b28af623dc17Chris Lattner  return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
3214a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                                 T.getCloseLocation());
322c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner}
323e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
324f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
325f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'.
326d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
32778b810559d89e996e00684335407443936ce34a1John McCall                                         const ParsedTemplateInfo &TemplateInfo,
32878b810559d89e996e00684335407443936ce34a1John McCall                                               SourceLocation &DeclEnd,
329c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                             ParsedAttributesWithRange &attrs,
330c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                               Decl **OwnedType) {
331f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_using) && "Not using token");
3329735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian  ObjCDeclContextSwitch ObjCDC(*this);
3339735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian
334f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'using'.
335f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation UsingLoc = ConsumeToken();
336f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
33749f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
33823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteUsing(getCurScope());
3397d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
3407d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
34149f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
342193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
34378b810559d89e996e00684335407443936ce34a1John McCall  // 'using namespace' means this is a using-directive.
34478b810559d89e996e00684335407443936ce34a1John McCall  if (Tok.is(tok::kw_namespace)) {
34578b810559d89e996e00684335407443936ce34a1John McCall    // Template parameters are always an error here.
34678b810559d89e996e00684335407443936ce34a1John McCall    if (TemplateInfo.Kind) {
34778b810559d89e996e00684335407443936ce34a1John McCall      SourceRange R = TemplateInfo.getSourceRange();
34878b810559d89e996e00684335407443936ce34a1John McCall      Diag(UsingLoc, diag::err_templated_using_directive)
34978b810559d89e996e00684335407443936ce34a1John McCall        << R << FixItHint::CreateRemoval(R);
35078b810559d89e996e00684335407443936ce34a1John McCall    }
35178b810559d89e996e00684335407443936ce34a1John McCall
3529735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian    return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
35378b810559d89e996e00684335407443936ce34a1John McCall  }
354bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
355162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  // Otherwise, it must be a using-declaration or an alias-declaration.
35678b810559d89e996e00684335407443936ce34a1John McCall
35778b810559d89e996e00684335407443936ce34a1John McCall  // Using declarations can't have attributes.
3587f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  ProhibitAttributes(attrs);
3592f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner
3609735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian  return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd,
361a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian                                    AS_none, OwnedType);
362f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
363f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
364f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes
365f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed.
366f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
367f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       using-directive: [C++ 7.3.p4: namespace.udir]
368f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
369f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name ;
370f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive:
371f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
372f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name attributes[opt] ;
373f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
374d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirective(unsigned Context,
37578b810559d89e996e00684335407443936ce34a1John McCall                                  SourceLocation UsingLoc,
37678b810559d89e996e00684335407443936ce34a1John McCall                                  SourceLocation &DeclEnd,
3777f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                  ParsedAttributes &attrs) {
378f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
379f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
380f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'namespace'.
381f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation NamespcLoc = ConsumeToken();
382f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
38349f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
38423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteUsingDirective(getCurScope());
3857d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
3867d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
38749f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
388193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
389f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  CXXScopeSpec SS;
390f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse (optional) nested-name-specifier.
391efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
392f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
393f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  IdentifierInfo *NamespcName = 0;
394f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation IdentLoc = SourceLocation();
395f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
396f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse namespace-name.
397823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
398f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    Diag(Tok, diag::err_expected_namespace_name);
399f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // If there was invalid namespace name, skip to end of decl, and eat ';'.
400f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    SkipUntil(tok::semi);
401f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
402d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
403f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  }
4041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
405823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse identifier.
406823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  NamespcName = Tok.getIdentifierInfo();
407823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  IdentLoc = ConsumeToken();
4081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
409823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse (optional) attributes (most likely GNU strong-using extension).
410bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  bool GNUAttr = false;
411bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Tok.is(tok::kw___attribute)) {
412bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    GNUAttr = true;
4137f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
414bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
4151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
416823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Eat ';'.
41797144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
4186869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi,
4199ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                   GNUAttr ? diag::err_expected_semi_after_attribute_list
4209ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                           : diag::err_expected_semi_after_namespace_name,
4219ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                   "", tok::semi);
422f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
42323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
4247f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                     IdentLoc, NamespcName, attrs.getList());
425f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
426f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
427162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration.
428162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// Assumes that 'using' was already seen.
429f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
430f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///     using-declaration: [C++ 7.3.p3: namespace.udecl]
431f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       'using' 'typename'[opt] ::[opt] nested-name-specifier
4329cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///               unqualified-id
4339cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///       'using' :: unqualified-id
434f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
435162e1c1b487352434552147967c3dd296ebee2f7Richard Smith///     alias-declaration: C++0x [decl.typedef]p2
436162e1c1b487352434552147967c3dd296ebee2f7Richard Smith///       'using' identifier = type-id ;
437162e1c1b487352434552147967c3dd296ebee2f7Richard Smith///
438d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDeclaration(unsigned Context,
43978b810559d89e996e00684335407443936ce34a1John McCall                                    const ParsedTemplateInfo &TemplateInfo,
44078b810559d89e996e00684335407443936ce34a1John McCall                                    SourceLocation UsingLoc,
44178b810559d89e996e00684335407443936ce34a1John McCall                                    SourceLocation &DeclEnd,
442c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                    AccessSpecifier AS,
443c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                    Decl **OwnedType) {
4449cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  CXXScopeSpec SS;
4457ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall  SourceLocation TypenameLoc;
4469cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  bool IsTypeName;
4479cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
4489cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Ignore optional 'typename'.
44912c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // FIXME: This is wrong; we should parse this as a typename-specifier.
4509cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_typename)) {
4517ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall    TypenameLoc = Tok.getLocation();
4529cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    ConsumeToken();
4539cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = true;
4549cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
4559cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  else
4569cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = false;
4579cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
4589cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Parse nested-name-specifier.
459efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
4609cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
4619cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Check nested-name specifier.
4629cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (SS.isInvalid()) {
4639cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
464d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
4659cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
4661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
467193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  // Parse the unqualified-id. We allow parsing of both constructor and
46812c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // destructor names and allow the action module to diagnose any semantic
46912c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // errors.
470e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  SourceLocation TemplateKWLoc;
47112c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  UnqualifiedId Name;
472193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  if (ParseUnqualifiedId(SS,
47312c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*EnteringContext=*/false,
47412c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*AllowDestructorName=*/true,
475193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                         /*AllowConstructorName=*/true,
476b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                         ParsedType(),
477e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                         TemplateKWLoc,
47812c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         Name)) {
4799cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
480d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
4819cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
482193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
4830b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
484162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
485162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  // Maybe this is an alias-declaration.
486162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  bool IsAliasDecl = Tok.is(tok::equal);
487162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  TypeResult TypeAlias;
488162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (IsAliasDecl) {
4893e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    // TODO: Attribute support. C++0x attributes may appear before the equals.
4903e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    // Where can GNU attributes appear?
491162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    ConsumeToken();
492162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
4934e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    Diag(Tok.getLocation(), getLangOpts().CPlusPlus0x ?
4947fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith         diag::warn_cxx98_compat_alias_declaration :
4957fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith         diag::ext_alias_declaration);
496162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
4973e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    // Type alias templates cannot be specialized.
4983e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    int SpecKind = -1;
499536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&
500536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith        Name.getKind() == UnqualifiedId::IK_TemplateId)
5013e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 0;
5023e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)
5033e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 1;
5043e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
5053e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 2;
5063e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (SpecKind != -1) {
5073e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SourceRange Range;
5083e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      if (SpecKind == 0)
5093e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        Range = SourceRange(Name.TemplateId->LAngleLoc,
5103e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                            Name.TemplateId->RAngleLoc);
5113e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      else
5123e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        Range = TemplateInfo.getSourceRange();
5133e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      Diag(Range.getBegin(), diag::err_alias_declaration_specialization)
5143e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        << SpecKind << Range;
5153e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SkipUntil(tok::semi);
5163e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      return 0;
5173e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    }
5183e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
519162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    // Name must be an identifier.
520162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    if (Name.getKind() != UnqualifiedId::IK_Identifier) {
521162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(Name.StartLocation, diag::err_alias_declaration_not_identifier);
522162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      // No removal fixit: can't recover from this.
523162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      SkipUntil(tok::semi);
524162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      return 0;
525162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    } else if (IsTypeName)
526162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(TypenameLoc, diag::err_alias_declaration_not_identifier)
527162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        << FixItHint::CreateRemoval(SourceRange(TypenameLoc,
528162e1c1b487352434552147967c3dd296ebee2f7Richard Smith                             SS.isNotEmpty() ? SS.getEndLoc() : TypenameLoc));
529162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    else if (SS.isNotEmpty())
530162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
531162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        << FixItHint::CreateRemoval(SS.getRange());
532162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
5333e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    TypeAlias = ParseTypeName(0, TemplateInfo.Kind ?
5343e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                              Declarator::AliasTemplateContext :
535cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall                              Declarator::AliasDeclContext, AS, OwnedType);
536162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  } else
537162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    // Parse (optional) attributes (most likely GNU strong-using extension).
538162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    MaybeParseGNUAttributes(attrs);
5391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5409cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Eat ';'.
5419cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  DeclEnd = Tok.getLocation();
5429cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
543162e1c1b487352434552147967c3dd296ebee2f7Richard Smith                   !attrs.empty() ? "attributes list" :
544162e1c1b487352434552147967c3dd296ebee2f7Richard Smith                   IsAliasDecl ? "alias declaration" : "using declaration",
54512c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                   tok::semi);
5469cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
54778b810559d89e996e00684335407443936ce34a1John McCall  // Diagnose an attempt to declare a templated using-declaration.
5483e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  // In C++0x, alias-declarations can be templates:
549162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  //   template <...> using id = type;
5503e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  if (TemplateInfo.Kind && !IsAliasDecl) {
55178b810559d89e996e00684335407443936ce34a1John McCall    SourceRange R = TemplateInfo.getSourceRange();
55278b810559d89e996e00684335407443936ce34a1John McCall    Diag(UsingLoc, diag::err_templated_using_declaration)
55378b810559d89e996e00684335407443936ce34a1John McCall      << R << FixItHint::CreateRemoval(R);
55478b810559d89e996e00684335407443936ce34a1John McCall
55578b810559d89e996e00684335407443936ce34a1John McCall    // Unfortunately, we have to bail out instead of recovering by
55678b810559d89e996e00684335407443936ce34a1John McCall    // ignoring the parameters, just in case the nested name specifier
55778b810559d89e996e00684335407443936ce34a1John McCall    // depends on the parameters.
55878b810559d89e996e00684335407443936ce34a1John McCall    return 0;
55978b810559d89e996e00684335407443936ce34a1John McCall  }
56078b810559d89e996e00684335407443936ce34a1John McCall
561480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  // "typename" keyword is allowed for identifiers only,
562480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  // because it may be a type definition.
563480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  if (IsTypeName && Name.getKind() != UnqualifiedId::IK_Identifier) {
564480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor    Diag(Name.getSourceRange().getBegin(), diag::err_typename_identifiers_only)
565480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor      << FixItHint::CreateRemoval(SourceRange(TypenameLoc));
566480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor    // Proceed parsing, but reset the IsTypeName flag.
567480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor    IsTypeName = false;
568480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  }
569480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor
5703e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  if (IsAliasDecl) {
5713e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
5723e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    MultiTemplateParamsArg TemplateParamsArg(Actions,
5733e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      TemplateParams ? TemplateParams->data() : 0,
5743e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      TemplateParams ? TemplateParams->size() : 0);
5753e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,
5763e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                         UsingLoc, Name, TypeAlias);
5773e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
578162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
5798113ecfa4e41e2c888b1794389dfe3bce6386493Ted Kremenek  return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS,
5807f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                       Name, attrs.getList(),
5817f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                       IsTypeName, TypenameLoc);
582f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
583f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
584ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer/// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration.
585511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
586c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// [C++0x] static_assert-declaration:
587c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///           static_assert ( constant-expression  ,  string-literal  ) ;
588c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///
589ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer/// [C11]   static_assert-declaration:
590c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///           _Static_assert ( constant-expression  ,  string-literal  ) ;
591511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
592d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
593c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne  assert((Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) &&
594c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne         "Not a static_assert declaration");
595c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne
5964e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11)
597ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer    Diag(Tok, diag::ext_c11_static_assert);
598841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith  if (Tok.is(tok::kw_static_assert))
599841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith    Diag(Tok, diag::warn_cxx98_compat_static_assert);
600c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne
601511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation StaticAssertLoc = ConsumeToken();
6021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6034a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
6044a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.consumeOpen()) {
605511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_lparen);
606d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
607511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
6081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60960d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult AssertExpr(ParseConstantExpression());
610511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (AssertExpr.isInvalid()) {
611511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    SkipUntil(tok::semi);
612d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
613511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
6141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
615ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
616d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
617ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson
6180cc323c6bed7206f9743a9775ec8d9cb90655f9cRichard Smith  if (!isTokenStringLiteral()) {
619511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_string_literal);
620511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    SkipUntil(tok::semi);
621d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
622511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
6231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62460d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult AssertMessage(ParseStringLiteralExpression());
62599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  if (AssertMessage.isInvalid()) {
62699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    SkipUntil(tok::semi);
627d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
62899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  }
629511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
6304a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
6311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
63297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
6339ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor  ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert);
634511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
6359ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc,
6369ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                              AssertExpr.take(),
637a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                              AssertMessage.take(),
6384a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                              T.getCloseLocation());
639511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson}
640511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
6416fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// ParseDecltypeSpecifier - Parse a C++0x decltype specifier.
6426fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
6436fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 'decltype' ( expression )
6446fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
64542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid BlaikieSourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
64642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  assert((Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype))
64742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie           && "Not a decltype specifier");
64842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
6496fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
65042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  ExprResult Result;
65142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  SourceLocation StartLoc = Tok.getLocation();
65242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  SourceLocation EndLoc;
6531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
65442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  if (Tok.is(tok::annot_decltype)) {
65542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    Result = getExprAnnotation(Tok);
65642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    EndLoc = Tok.getAnnotationEndLoc();
65742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    ConsumeToken();
65842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    if (Result.isInvalid()) {
65942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      DS.SetTypeSpecError();
66042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      return EndLoc;
66142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    }
66242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  } else {
663c7b5543ad32a5c265c02e71b2a6f9856440ed13fRichard Smith    if (Tok.getIdentifierInfo()->isStr("decltype"))
664c7b5543ad32a5c265c02e71b2a6f9856440ed13fRichard Smith      Diag(Tok, diag::warn_cxx98_compat_decltype);
66539304fad1c8a7b7e64121e9ae544b18e460b682cRichard Smith
66642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    ConsumeToken();
6671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
66842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    BalancedDelimiterTracker T(*this, tok::l_paren);
66942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    if (T.expectAndConsume(diag::err_expected_lparen_after,
67042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie                           "decltype", tok::r_paren)) {
67142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      DS.SetTypeSpecError();
67242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      return T.getOpenLocation() == Tok.getLocation() ?
67342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie             StartLoc : T.getOpenLocation();
67442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    }
6751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
67642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    // Parse the expression
67742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
67842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    // C++0x [dcl.type.simple]p4:
67942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    //   The operand of the decltype specifier is an unevaluated operand.
68076f3f69db1416425070177243e9f390122c553e0Richard Smith    EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
68176f3f69db1416425070177243e9f390122c553e0Richard Smith                                                 0, /*IsDecltype=*/true);
68242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    Result = ParseExpression();
68342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    if (Result.isInvalid()) {
684d8e4daca4a44d25a9c09d51def9e3d485d4f302cRichard Smith      SkipUntil(tok::r_paren);
68542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      DS.SetTypeSpecError();
686d8e4daca4a44d25a9c09d51def9e3d485d4f302cRichard Smith      return StartLoc;
68742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    }
68842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
68942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    // Match the ')'
69042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    T.consumeClose();
69142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    if (T.getCloseLocation().isInvalid()) {
69242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      DS.SetTypeSpecError();
69342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      // FIXME: this should return the location of the last token
69442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      //        that was consumed (by "consumeClose()")
69542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      return T.getCloseLocation();
69642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    }
69742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
69876f3f69db1416425070177243e9f390122c553e0Richard Smith    Result = Actions.ActOnDecltypeExpression(Result.take());
69976f3f69db1416425070177243e9f390122c553e0Richard Smith    if (Result.isInvalid()) {
70076f3f69db1416425070177243e9f390122c553e0Richard Smith      DS.SetTypeSpecError();
70176f3f69db1416425070177243e9f390122c553e0Richard Smith      return T.getCloseLocation();
70276f3f69db1416425070177243e9f390122c553e0Richard Smith    }
70376f3f69db1416425070177243e9f390122c553e0Richard Smith
70442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    EndLoc = T.getCloseLocation();
70542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  }
7066fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
7076fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  const char *PrevSpec = 0;
708fec54013fcd0eb72642741584ca04c1bc292bef8John McCall  unsigned DiagID;
7096fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Check for duplicate type specifiers (e.g. "int decltype(a)").
7101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec,
71142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie                         DiagID, Result.release())) {
712fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
71342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    DS.SetTypeSpecError();
71442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  }
71542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  return EndLoc;
71642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie}
71742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
71842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikievoid Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec& DS,
71942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie                                               SourceLocation StartLoc,
72042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie                                               SourceLocation EndLoc) {
72142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  // make sure we have a token we can turn into an annotation token
72242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  if (PP.isBacktrackEnabled())
72342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    PP.RevertCachedTokens(1);
72442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  else
72542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    PP.EnterToken(Tok);
72642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
72742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  Tok.setKind(tok::annot_decltype);
72842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  setExprAnnotation(Tok, DS.getTypeSpecType() == TST_decltype ?
72942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie                         DS.getRepAsExpr() : ExprResult());
73042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  Tok.setAnnotationEndLoc(EndLoc);
73142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  Tok.setLocation(StartLoc);
73242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  PP.AnnotateCachedTokens(Tok);
7336fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson}
7346fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
735db5d44b775c60166074acd184ca9f1981c10c2a7Sean Huntvoid Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) {
736db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  assert(Tok.is(tok::kw___underlying_type) &&
737db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt         "Not an underlying type specifier");
738db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
739db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  SourceLocation StartLoc = ConsumeToken();
7404a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
7414a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.expectAndConsume(diag::err_expected_lparen_after,
7424a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                       "__underlying_type", tok::r_paren)) {
743db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
744db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  }
745db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
746db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  TypeResult Result = ParseTypeName();
747db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  if (Result.isInvalid()) {
748db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    SkipUntil(tok::r_paren);
749db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
750db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  }
751db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
752db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  // Match the ')'
7534a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
7544a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.getCloseLocation().isInvalid())
755db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
756db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
757db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  const char *PrevSpec = 0;
758db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  unsigned DiagID;
759ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec,
760db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt                         DiagID, Result.release()))
761db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    Diag(StartLoc, DiagID) << PrevSpec;
762db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt}
763db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
76409048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// ParseBaseTypeSpecifier - Parse a C++ base-type-specifier which is either a
76509048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class name or decltype-specifier. Note that we only check that the result
76609048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// names a type; semantic analysis will need to verify that the type names a
76709048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class. The result is either a type or null, depending on whether a type
76809048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// name was found.
76942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///
77009048df0b3f472091b2204e531d6b6019244884bDavid Blaikie///       base-type-specifier: [C++ 10.1]
77109048df0b3f472091b2204e531d6b6019244884bDavid Blaikie///         class-or-decltype
77209048df0b3f472091b2204e531d6b6019244884bDavid Blaikie///       class-or-decltype: [C++ 10.1]
77309048df0b3f472091b2204e531d6b6019244884bDavid Blaikie///         nested-name-specifier[opt] class-name
77409048df0b3f472091b2204e531d6b6019244884bDavid Blaikie///         decltype-specifier
77542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///       class-name: [C++ 9.1]
77642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///         identifier
7777f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor///         simple-template-id
7781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
77922216eb4fb0936d2488fc03abd285d135c36ff01David BlaikieParser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
78022216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie                                                  SourceLocation &EndLocation) {
7817fe3878a36750515fb9772414ecb2489cf149d19David Blaikie  // Ignore attempts to use typename
7827fe3878a36750515fb9772414ecb2489cf149d19David Blaikie  if (Tok.is(tok::kw_typename)) {
7837fe3878a36750515fb9772414ecb2489cf149d19David Blaikie    Diag(Tok, diag::err_expected_class_name_not_template)
7847fe3878a36750515fb9772414ecb2489cf149d19David Blaikie      << FixItHint::CreateRemoval(Tok.getLocation());
7857fe3878a36750515fb9772414ecb2489cf149d19David Blaikie    ConsumeToken();
7867fe3878a36750515fb9772414ecb2489cf149d19David Blaikie  }
7877fe3878a36750515fb9772414ecb2489cf149d19David Blaikie
788152aa4b87633754801598ee282e1a17c3ec49257David Blaikie  // Parse optional nested-name-specifier
789152aa4b87633754801598ee282e1a17c3ec49257David Blaikie  CXXScopeSpec SS;
790152aa4b87633754801598ee282e1a17c3ec49257David Blaikie  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
791152aa4b87633754801598ee282e1a17c3ec49257David Blaikie
792152aa4b87633754801598ee282e1a17c3ec49257David Blaikie  BaseLoc = Tok.getLocation();
793152aa4b87633754801598ee282e1a17c3ec49257David Blaikie
79422216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie  // Parse decltype-specifier
79542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  // tok == kw_decltype is just error recovery, it can only happen when SS
79642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  // isn't empty
79742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  if (Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) {
798152aa4b87633754801598ee282e1a17c3ec49257David Blaikie    if (SS.isNotEmpty())
799152aa4b87633754801598ee282e1a17c3ec49257David Blaikie      Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype)
800152aa4b87633754801598ee282e1a17c3ec49257David Blaikie        << FixItHint::CreateRemoval(SS.getRange());
80122216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie    // Fake up a Declarator to use with ActOnTypeName.
80222216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie    DeclSpec DS(AttrFactory);
80322216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie
804b57775709666e50cd925f9fc589d0fd895fc79a6David Blaikie    EndLocation = ParseDecltypeSpecifier(DS);
80522216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie
80622216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie    Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
80722216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie    return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
80822216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie  }
80922216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie
8107f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  // Check whether we have a template-id that names a type.
8117f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  if (Tok.is(tok::annot_template_id)) {
81225a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
813d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor    if (TemplateId->Kind == TNK_Type_template ||
814d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor        TemplateId->Kind == TNK_Dependent_template_name) {
815059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
8167f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
8177f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
818b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      ParsedType Type = getTypeAnnotation(Tok);
8197f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      EndLocation = Tok.getAnnotationEndLoc();
8207f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      ConsumeToken();
82131a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor
82231a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      if (Type)
82331a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor        return Type;
82431a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      return true;
8257f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    }
8267f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
8277f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    // Fall through to produce an error below.
8287f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  }
8297f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
83042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  if (Tok.isNot(tok::identifier)) {
8311ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_class_name);
83231a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
83342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
83442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
83584d0a19828599e8623223632d59447fd498999cfDouglas Gregor  IdentifierInfo *Id = Tok.getIdentifierInfo();
83684d0a19828599e8623223632d59447fd498999cfDouglas Gregor  SourceLocation IdLoc = ConsumeToken();
83784d0a19828599e8623223632d59447fd498999cfDouglas Gregor
83884d0a19828599e8623223632d59447fd498999cfDouglas Gregor  if (Tok.is(tok::less)) {
83984d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // It looks the user intended to write a template-id here, but the
84084d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // template-name was wrong. Try to fix that.
84184d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateNameKind TNK = TNK_Type_template;
84284d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateTy Template;
84323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(),
844059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                             &SS, Template, TNK)) {
84584d0a19828599e8623223632d59447fd498999cfDouglas Gregor      Diag(IdLoc, diag::err_unknown_template_name)
84684d0a19828599e8623223632d59447fd498999cfDouglas Gregor        << Id;
84784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    }
848193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
84984d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (!Template)
85084d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
85184d0a19828599e8623223632d59447fd498999cfDouglas Gregor
852193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam    // Form the template name
85384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    UnqualifiedId TemplateName;
85484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateName.setIdentifier(Id, IdLoc);
855193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
85684d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // Parse the full template-id, then turn it into a type.
857e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
858e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                                TemplateName, true))
85984d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
86084d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (TNK == TNK_Dependent_template_name)
861059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
862193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
86384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // If we didn't end up with a typename token, there's nothing more we
86484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // can do.
86584d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (Tok.isNot(tok::annot_typename))
86684d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
867193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
86884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // Retrieve the type from the annotation token, consume that token, and
86984d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // return.
87084d0a19828599e8623223632d59447fd498999cfDouglas Gregor    EndLocation = Tok.getAnnotationEndLoc();
871b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    ParsedType Type = getTypeAnnotation(Tok);
87284d0a19828599e8623223632d59447fd498999cfDouglas Gregor    ConsumeToken();
87384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    return Type;
87484d0a19828599e8623223632d59447fd498999cfDouglas Gregor  }
87584d0a19828599e8623223632d59447fd498999cfDouglas Gregor
87642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // We have an identifier; check whether it is actually a type.
877059101f922de6eb765601459925f4c8914420b23Douglas Gregor  ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true,
8789e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor                                        false, ParsedType(),
879fad03b75e0297546c5d12ec420b5b79d5b7baa2aAbramo Bagnara                                        /*IsCtorOrDtorName=*/false,
8809e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor                                        /*NonTrivialTypeSourceInfo=*/true);
881193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  if (!Type) {
882124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor    Diag(IdLoc, diag::err_expected_class_name);
88331a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
88442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
88542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
88642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Consume the identifier.
88784d0a19828599e8623223632d59447fd498999cfDouglas Gregor  EndLocation = IdLoc;
8885606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
8895606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  // Fake up a Declarator to use with ActOnTypeName.
8900b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  DeclSpec DS(AttrFactory);
8915606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetRangeStart(IdLoc);
8925606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetRangeEnd(EndLocation);
893059101f922de6eb765601459925f4c8914420b23Douglas Gregor  DS.getTypeSpecScope() = SS;
8945606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
8955606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  const char *PrevSpec = 0;
8965606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  unsigned DiagID;
8975606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type);
8985606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
8995606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
9005606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
90142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor}
90242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
903e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
904e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
905e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that
90669730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith/// cannot start a definition.
907e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
908e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-specifier: [C++ class]
909e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}'
910e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}' attributes[opt]
911e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-head:
912e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key identifier[opt] base-clause[opt]
913e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier identifier base-clause[opt]
914e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier[opt] simple-template-id
915e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          base-clause[opt]
916e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   class-key attributes[opt] identifier[opt] base-clause[opt]
9171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier
918e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          identifier base-clause[opt]
9191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier[opt]
920e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          simple-template-id base-clause[opt]
921e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-key:
922e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'class'
923e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
924e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
925e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
926e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       elaborated-type-specifier: [C++ dcl.type.elab]
9271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] identifier
9281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
9291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///                          simple-template-id
930e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
931e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  Note that the C++ class-specifier and elaborated-type-specifier,
932e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  together, subsume the C99 struct-or-union-specifier:
933e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
934e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union-specifier: [C99 6.7.2.1]
935e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier[opt] '{' struct-contents '}'
936e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier
937e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier[opt] '{' struct-contents
938e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                                                         '}' attributes[opt]
939e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier
940e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union:
941e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
942e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
9434c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattnervoid Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
9444c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner                                 SourceLocation StartLoc, DeclSpec &DS,
9454d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                 const ParsedTemplateInfo &TemplateInfo,
946efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor                                 AccessSpecifier AS,
94769730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith                                 bool EnteringContext, DeclSpecContext DSC) {
9484c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  DeclSpec::TST TagType;
9494c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  if (TagTokKind == tok::kw_struct)
9504c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_struct;
9514c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  else if (TagTokKind == tok::kw_class)
9524c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_class;
9534c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  else {
9544c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    assert(TagTokKind == tok::kw_union && "Not a class specifier");
9554c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_union;
9564c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  }
957e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
958374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  if (Tok.is(tok::code_completion)) {
959374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor    // Code completion for a struct, class, or union name.
96023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteTag(getCurScope(), TagType);
9617d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return cutOffParsing();
962374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  }
963193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
964926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // C++03 [temp.explicit] 14.7.2/8:
965926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //   The usual access checking rules do not apply to names used to specify
966926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //   explicit instantiations.
967926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //
968926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // As an extension we do not perform access checking on the names used to
969926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // specify explicit specializations either. This is important to allow
970926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // specializing traits classes for private types.
9711af83c444e5a2f6f50a6e1c15e6ebc618ae18a5fRichard Smith  Sema::SuppressAccessChecksRAII SuppressAccess(Actions,
9721af83c444e5a2f6f50a6e1c15e6ebc618ae18a5fRichard Smith    TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
9731af83c444e5a2f6f50a6e1c15e6ebc618ae18a5fRichard Smith    TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
974926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
9750b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
976e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If attributes exist after tag, parse them.
977e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw___attribute))
9787f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
979e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
980f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff  // If declspecs exist after tag, parse them.
981b1d397c23e1f8fd8b404d5731d531e7500f7140dJohn McCall  while (Tok.is(tok::kw___declspec))
9827f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseMicrosoftDeclSpec(attrs);
983193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
984bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // If C++0x attributes exist here, parse them.
985bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Are we consistent with the ordering of parsing of different
986bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // styles of attributes?
9877f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseCXX0XAttributes(attrs);
9881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
98920c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley  if (TagType == DeclSpec::TST_struct &&
990b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      !Tok.is(tok::identifier) &&
991b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      Tok.getIdentifierInfo() &&
992b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      (Tok.is(tok::kw___is_arithmetic) ||
993b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_convertible) ||
99420c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley       Tok.is(tok::kw___is_empty) ||
995b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_floating_point) ||
996b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_function) ||
99720c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley       Tok.is(tok::kw___is_fundamental) ||
998b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_integral) ||
999b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_member_function_pointer) ||
1000b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_member_pointer) ||
1001b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_pod) ||
1002b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_pointer) ||
1003b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_same) ||
1004877222e2491bbc40a5c74cc100c540983f306b70Douglas Gregor       Tok.is(tok::kw___is_scalar) ||
1005b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_signed) ||
1006b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_unsigned) ||
1007b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_void))) {
1008688761409155b47c39eb5dae1b8c6c8a9f43307aDouglas Gregor    // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the
1009b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // name of struct templates, but some are keywords in GCC >= 4.3
1010b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // and Clang. Therefore, when we see the token sequence "struct
1011b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // X", make X into a normal identifier rather than a keyword, to
1012b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // allow libstdc++ 4.2 and libc++ to work properly.
1013646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
1014b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.setKind(tok::identifier);
1015b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  }
10161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1017eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse the (optional) nested-name-specifier.
1018aa87d33309f505b68c3bfc17486c93e4d224b24fJohn McCall  CXXScopeSpec &SS = DS.getTypeSpecScope();
10194e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().CPlusPlus) {
102008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    // "FOO : BAR" is not a potential typo for "FOO::BAR".
102108d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    ColonProtectionRAIIObject X(*this);
1022193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1023efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor    if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext))
1024207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      DS.SetTypeSpecError();
10259ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall    if (SS.isSet())
102608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner      if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
102708d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner        Diag(Tok, diag::err_expected_ident);
102808d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  }
1029cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
10302cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor  TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
10312cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor
1032cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  // Parse the (optional) class name or simple-template-id.
1033e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  IdentifierInfo *Name = 0;
1034e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation NameLoc;
103539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  TemplateIdAnnotation *TemplateId = 0;
1036e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::identifier)) {
1037e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    Name = Tok.getIdentifierInfo();
1038e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    NameLoc = ConsumeToken();
1039193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
10404e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (Tok.is(tok::less) && getLangOpts().CPlusPlus) {
1041193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      // The name was supposed to refer to a template, but didn't.
10422cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // Eat the template argument list and try to continue parsing this as
10432cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // a class (or template thereof).
10442cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      TemplateArgList TemplateArgs;
10452cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      SourceLocation LAngleLoc, RAngleLoc;
1046059101f922de6eb765601459925f4c8914420b23Douglas Gregor      if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, SS,
10472cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor                                           true, LAngleLoc,
1048314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor                                           TemplateArgs, RAngleLoc)) {
10492cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // We couldn't parse the template argument list at all, so don't
10502cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // try to give any location information for the list.
10512cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        LAngleLoc = RAngleLoc = SourceLocation();
10522cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
1053193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
10542cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      Diag(NameLoc, diag::err_explicit_spec_non_template)
1055c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
10562cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << (TagType == DeclSpec::TST_class? 0
10572cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor            : TagType == DeclSpec::TST_struct? 1
10582cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor            : 2)
10592cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << Name
10602cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << SourceRange(LAngleLoc, RAngleLoc);
1061193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1062193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      // Strip off the last template parameter list if it was empty, since
1063c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      // we've removed its template argument list.
1064c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
1065c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        if (TemplateParams && TemplateParams->size() > 1) {
1066c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams->pop_back();
1067c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        } else {
1068c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams = 0;
1069193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam          const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
1070c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor            = ParsedTemplateInfo::NonTemplate;
1071c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        }
1072c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      } else if (TemplateInfo.Kind
1073c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor                                == ParsedTemplateInfo::ExplicitInstantiation) {
1074c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        // Pretend this is just a forward declaration.
10752cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        TemplateParams = 0;
1076193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam        const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
10772cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor          = ParsedTemplateInfo::NonTemplate;
1078193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam        const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc
1079c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
1080c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc
1081c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
10822cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
10832cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor    }
108439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  } else if (Tok.is(tok::annot_template_id)) {
108525a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis    TemplateId = takeTemplateIdAnnotation(Tok);
108639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    NameLoc = ConsumeToken();
1087cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
1088059101f922de6eb765601459925f4c8914420b23Douglas Gregor    if (TemplateId->Kind != TNK_Type_template &&
1089059101f922de6eb765601459925f4c8914420b23Douglas Gregor        TemplateId->Kind != TNK_Dependent_template_name) {
109039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // The template-name in the simple-template-id refers to
109139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // something other than a class template. Give an appropriate
109239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // error message and skip to the ';'.
109339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SourceRange Range(NameLoc);
109439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      if (SS.isNotEmpty())
109539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        Range.setBegin(SS.getBeginLoc());
109639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
109739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
109839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        << Name << static_cast<int>(TemplateId->Kind) << Range;
10991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
110039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      DS.SetTypeSpecError();
110139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SkipUntil(tok::semi, false, true);
110239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      return;
1103cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    }
1104e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1105e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1106926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // As soon as we're finished parsing the class's template-id, turn access
1107926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // checking back on.
11081af83c444e5a2f6f50a6e1c15e6ebc618ae18a5fRichard Smith  SuppressAccess.done();
1109926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
11107796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  // There are four options here.
11117796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //  - If we are in a trailing return type, this is always just a reference,
11127796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //    and we must not try to parse a definition. For instance,
11137796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //      [] () -> struct S { };
11147796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //    does not define a type.
11157796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //  - If we have 'struct foo {...', 'struct foo :...',
11167796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //    'struct foo final :' or 'struct foo final {', then this is a definition.
11177796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //  - If we have 'struct foo;', then this is either a forward declaration
11187796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //    or a friend declaration, which have to be treated differently.
11197796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //  - Otherwise we have something like 'struct foo xyz', a reference.
112069730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  // However, in type-specifier-seq's, things look like declarations but are
112169730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  // just references, e.g.
112269730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  //   new struct s;
1123d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // or
112469730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  //   &T::operator struct s;
112569730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  // For these, DSC is DSC_type_specifier.
1126f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  Sema::TagUseKind TUK;
11277796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  if (DSC == DSC_trailing)
11287796eb5643244f3134834253ce5ea89107ac21c1Richard Smith    TUK = Sema::TUK_Reference;
11297796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  else if (Tok.is(tok::l_brace) ||
11307796eb5643244f3134834253ce5ea89107ac21c1Richard Smith           (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
11317796eb5643244f3134834253ce5ea89107ac21c1Richard Smith           (isCXX0XFinalKeyword() &&
11326f42669b7c0b81b07a15a0483aa5e897ce57cb45David Blaikie            (NextToken().is(tok::l_brace) || NextToken().is(tok::colon)))) {
1133d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    if (DS.isFriendSpecified()) {
1134d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // C++ [class.friend]p2:
1135d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      //   A class shall not be defined in a friend declaration.
1136bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith      Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
1137d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor        << SourceRange(DS.getFriendSpecLoc());
1138d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor
1139d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Skip everything up to the semicolon, so that this looks like a proper
1140d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // friend class (or template thereof) declaration.
1141d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      SkipUntil(tok::semi, true, true);
1142f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall      TUK = Sema::TUK_Friend;
1143d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    } else {
1144d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Okay, this is a class definition.
1145f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall      TUK = Sema::TUK_Definition;
1146d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    }
114769730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  } else if (Tok.is(tok::semi) && DSC != DSC_type_specifier)
1148f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
1149e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  else
1150f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = Sema::TUK_Reference;
1151e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1152207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall  if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error ||
1153f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                               TUK != Sema::TUK_Definition)) {
1154207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall    if (DS.getTypeSpecType() != DeclSpec::TST_error) {
1155207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      // We have a declaration or reference to an anonymous class.
1156207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      Diag(StartLoc, diag::err_anon_type_definition)
1157207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall        << DeclSpec::getSpecifierName(TagType);
1158207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall    }
1159e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1160e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SkipUntil(tok::comma, true);
1161e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    return;
1162e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1163e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1164ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  // Create the tag portion of the class or class template.
1165d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  DeclResult TagOrTempResult = true; // invalid
1166d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  TypeResult TypeResult = true; // invalid
11674d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
1168402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor  bool Owned = false;
1169f1bbbb49f06a7462476cd88166fccda5feb15cabJohn McCall  if (TemplateId) {
11704d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // Explicit specialization, class template partial specialization,
11714d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // or explicit instantiation.
11721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ASTTemplateArgsPtr TemplateArgsPtr(Actions,
117339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->getTemplateArgs(),
117439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->NumArgs);
11754d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1176f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        TUK == Sema::TUK_Declaration) {
11774d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit instantiation of a class template.
11784d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
117923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        = Actions.ActOnExplicitInstantiation(getCurScope(),
118045f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                             TemplateInfo.ExternLoc,
11811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateInfo.TemplateLoc,
11824d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TagType,
11831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             StartLoc,
11844d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             SS,
11852b5289b6fd7e3d9899868410a498c081c9595662John McCall                                             TemplateId->Template,
11861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->TemplateNameLoc,
11871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->LAngleLoc,
11884d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateArgsPtr,
11891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->RAngleLoc,
11907f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                             attrs.getList());
119174256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall
119274256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // Friend template-ids are treated as references unless
119374256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // they have template headers, in which case they're ill-formed
119474256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // (FIXME: "template <class T> friend class A<T>::B<int>;").
119574256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // We diagnose this error in ActOnClassTemplateSpecialization.
1196f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    } else if (TUK == Sema::TUK_Reference ||
1197f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall               (TUK == Sema::TUK_Friend &&
119874256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall                TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
119955d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara      TypeResult = Actions.ActOnTagTemplateIdType(TUK, TagType, StartLoc,
1200059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->SS,
120155d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara                                                  TemplateId->TemplateKWLoc,
1202059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->Template,
1203059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->TemplateNameLoc,
1204059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->LAngleLoc,
1205059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateArgsPtr,
120655d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara                                                  TemplateId->RAngleLoc);
12074d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    } else {
12084d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit specialization or a class template
12094d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // partial specialization.
12104d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TemplateParameterLists FakedParamLists;
12114d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
12124d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
12134d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // This looks like an explicit instantiation, because we have
12144d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // something like
12154d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
12164d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //   template class Foo<X>
12174d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
12183f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor        // but it actually has a definition. Most likely, this was
12194d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // meant to be an explicit specialization, but the user forgot
12204d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // the '<>' after 'template'.
1221f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        assert(TUK == Sema::TUK_Definition && "Expected a definition here");
12224d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
12231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        SourceLocation LAngleLoc
12244d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
12251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        Diag(TemplateId->TemplateNameLoc,
12264d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor             diag::err_explicit_instantiation_with_definition)
12274d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          << SourceRange(TemplateInfo.TemplateLoc)
1228849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor          << FixItHint::CreateInsertion(LAngleLoc, "<>");
12294d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
12304d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // Create a fake template parameter list that contains only
12314d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // "template<>", so that we treat this construct as a class
12324d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // template specialization.
12334d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        FakedParamLists.push_back(
12341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          Actions.ActOnTemplateParameterList(0, SourceLocation(),
12354d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateInfo.TemplateLoc,
12361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             LAngleLoc,
12371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             0, 0,
12384d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             LAngleLoc));
12394d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        TemplateParams = &FakedParamLists;
12404d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      }
12414d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
12424d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // Build the class template specialization.
12434d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
124423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK,
1245d023aec8907831a18d3514a95b843a7ee06b6b5eDouglas Gregor                       StartLoc, DS.getModulePrivateSpecLoc(), SS,
12462b5289b6fd7e3d9899868410a498c081c9595662John McCall                       TemplateId->Template,
12471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->TemplateNameLoc,
12481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->LAngleLoc,
124939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       TemplateArgsPtr,
12501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->RAngleLoc,
12517f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                       attrs.getList(),
1252f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                       MultiTemplateParamsArg(Actions,
1253cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                    TemplateParams? &(*TemplateParams)[0] : 0,
1254cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                 TemplateParams? TemplateParams->size() : 0));
12554d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    }
12563f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1257f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall             TUK == Sema::TUK_Declaration) {
12583f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Explicit instantiation of a member of a class template
12593f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // specialization, e.g.,
12603f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
12613f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //   template struct Outer<int>::Inner;
12623f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
12633f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    TagOrTempResult
126423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      = Actions.ActOnExplicitInstantiation(getCurScope(),
126545f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                           TemplateInfo.ExternLoc,
12661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TemplateInfo.TemplateLoc,
12671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TagType, StartLoc, SS, Name,
12687f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                           NameLoc, attrs.getList());
12699a34edb710917798aa30263374f624f13b594605John McCall  } else if (TUK == Sema::TUK_Friend &&
12709a34edb710917798aa30263374f624f13b594605John McCall             TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
12719a34edb710917798aa30263374f624f13b594605John McCall    TagOrTempResult =
12729a34edb710917798aa30263374f624f13b594605John McCall      Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(),
12739a34edb710917798aa30263374f624f13b594605John McCall                                      TagType, StartLoc, SS,
12747f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                      Name, NameLoc, attrs.getList(),
12759a34edb710917798aa30263374f624f13b594605John McCall                                      MultiTemplateParamsArg(Actions,
12769a34edb710917798aa30263374f624f13b594605John McCall                                    TemplateParams? &(*TemplateParams)[0] : 0,
12779a34edb710917798aa30263374f624f13b594605John McCall                                 TemplateParams? TemplateParams->size() : 0));
12783f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else {
12793f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1280f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        TUK == Sema::TUK_Definition) {
12813f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor      // FIXME: Diagnose this particular error.
12823f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    }
12833f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor
1284c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    bool IsDependent = false;
1285c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
1286a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    // Don't pass down template parameter lists if this is just a tag
1287a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    // reference.  For example, we don't need the template parameters here:
1288a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    //   template <class T> class A *makeA(T t);
1289a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    MultiTemplateParamsArg TParams;
1290a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    if (TUK != Sema::TUK_Reference && TemplateParams)
1291a25c4080a490ea2bab6f54094dd75b19eae83770John McCall      TParams =
1292a25c4080a490ea2bab6f54094dd75b19eae83770John McCall        MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size());
1293a25c4080a490ea2bab6f54094dd75b19eae83770John McCall
12943f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Declaration or definition of a class type
12959a34edb710917798aa30263374f624f13b594605John McCall    TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc,
12967f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                       SS, Name, NameLoc, attrs.getList(), AS,
1297e761230ae3751b525cadd8066c74ec278ee4ef57Douglas Gregor                                       DS.getModulePrivateSpecLoc(),
1298bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith                                       TParams, Owned, IsDependent,
1299bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith                                       SourceLocation(), false,
1300bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith                                       clang::TypeResult());
1301c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
1302c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // If ActOnTag said the type was dependent, try again with the
1303c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // less common call.
13049a34edb710917798aa30263374f624f13b594605John McCall    if (IsDependent) {
13059a34edb710917798aa30263374f624f13b594605John McCall      assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend);
130623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK,
1307193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                                             SS, Name, StartLoc, NameLoc);
13089a34edb710917798aa30263374f624f13b594605John McCall    }
13093f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  }
1310e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1311e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If there is a body, parse it and inform the actions module.
1312f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  if (TUK == Sema::TUK_Definition) {
1313bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    assert(Tok.is(tok::l_brace) ||
13144e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie           (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
13158a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson           isCXX0XFinalKeyword());
13164e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().CPlusPlus)
1317212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
131807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    else
1319212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
1320e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1321e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1322b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  const char *PrevSpec = 0;
1323b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  unsigned DiagID;
1324b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  bool Result;
1325c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  if (!TypeResult.isInvalid()) {
13260daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara    Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
13270daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                NameLoc.isValid() ? NameLoc : StartLoc,
1328b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                PrevSpec, DiagID, TypeResult.get());
1329c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else if (!TagOrTempResult.isInvalid()) {
13300daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara    Result = DS.SetTypeSpecType(TagType, StartLoc,
13310daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                NameLoc.isValid() ? NameLoc : StartLoc,
13320daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                PrevSpec, DiagID, TagOrTempResult.get(), Owned);
1333c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else {
1334ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    DS.SetTypeSpecError();
133566e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson    return;
133666e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson  }
13371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1338b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  if (Result)
1339fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
1340193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
13414ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // At this point, we've successfully parsed a class-specifier in 'definition'
13424ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // form (e.g. "struct foo { int x; }".  While we could just return here, we're
13434ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // going to look at what comes after it to improve error recovery.  If an
13444ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // impossible token occurs next, we assume that the programmer forgot a ; at
13454ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // the end of the declaration and recover that way.
13464ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  //
13474ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // This switch enumerates the valid "follow" set for definition.
1348f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  if (TUK == Sema::TUK_Definition) {
1349b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    bool ExpectedSemi = true;
13504ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    switch (Tok.getKind()) {
1351b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    default: break;
13524ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    case tok::semi:               // struct foo {...} ;
135399c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::star:               // struct foo {...} *         P;
135499c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::amp:                // struct foo {...} &         R = ...
135599c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::identifier:         // struct foo {...} V         ;
135699c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::r_paren:            //(struct foo {...} )         {4}
135799c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_cxxscope:     // struct foo {...} a::       b;
135899c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_typename:     // struct foo {...} a         ::b;
135999c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_template_id:  // struct foo {...} a<int>    ::b;
1360c2e1c1af8ffe750b827284f207b9207112c7cc4eChris Lattner    case tok::l_paren:            // struct foo {...} (         x);
136116acfee729e00536af827935ccfcf69be721e462Chris Lattner    case tok::comma:              // __builtin_offsetof(struct foo{...} ,
1362b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      ExpectedSemi = false;
1363b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      break;
1364b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    // Type qualifiers
1365b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_const:           // struct foo {...} const     x;
1366b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_volatile:        // struct foo {...} volatile  x;
1367b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_restrict:        // struct foo {...} restrict  x;
1368b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_inline:          // struct foo {...} inline    foo() {};
136999c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    // Storage-class specifiers
137099c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_static:          // struct foo {...} static    x;
137199c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_extern:          // struct foo {...} extern    x;
137299c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_typedef:         // struct foo {...} typedef   x;
137399c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_register:        // struct foo {...} register  x;
137499c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_auto:            // struct foo {...} auto      x;
1375af1fc7af351758b0ea0d285bdfe5640128109a4eRichard Smith    case tok::kw_mutable:         // struct foo {...} mutable   x;
1376af1fc7af351758b0ea0d285bdfe5640128109a4eRichard Smith    case tok::kw_constexpr:       // struct foo {...} constexpr x;
1377b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // As shown above, type qualifiers and storage class specifiers absolutely
1378b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // can occur after class specifiers according to the grammar.  However,
1379fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner      // almost no one actually writes code like this.  If we see one of these,
1380b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // it is much more likely that someone missed a semi colon and the
1381b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // type/storage class specifier we're seeing is part of the *next*
1382b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // intended declaration, as in:
1383b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //
1384b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //   struct foo { ... }
1385b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //   typedef int X;
1386b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //
1387b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // We'd really like to emit a missing semicolon error instead of emitting
1388b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // an error on the 'int' saying that you can't have two type specifiers in
1389b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // the same declaration of X.  Because of this, we look ahead past this
1390b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // token to see if it's a type specifier.  If so, we know the code is
1391b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // otherwise invalid, so we can produce the expected semi error.
1392b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      if (!isKnownToBeTypeSpecifier(NextToken()))
1393b3a4e432c90be98c6d918087750397e86d030368Chris Lattner        ExpectedSemi = false;
13944ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      break;
1395193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1396193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam    case tok::r_brace:  // struct bar { struct foo {...} }
13974ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // Missing ';' at end of struct is accepted as an extension in C mode.
13984e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      if (!getLangOpts().CPlusPlus)
1399b3a4e432c90be98c6d918087750397e86d030368Chris Lattner        ExpectedSemi = false;
1400b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      break;
1401b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    }
1402193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1403cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith    // C++ [temp]p3 In a template-declaration which defines a class, no
1404cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith    // declarator is permitted.
1405cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith    if (TemplateInfo.Kind)
1406cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith      ExpectedSemi = true;
1407cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith
1408b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    if (ExpectedSemi) {
14094ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
14104ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner                       TagType == DeclSpec::TST_class ? "class"
14114ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner                       : TagType == DeclSpec::TST_struct? "struct" : "union");
14124ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // Push this token back into the preprocessor and change our current token
14134ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // to ';' so that the rest of the code recovers as though there were an
14144ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // ';' after the definition.
14154ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      PP.EnterToken(Tok);
1416193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      Tok.setKind(tok::semi);
14174ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    }
14184ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  }
1419e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1420e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
14211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
1422e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1423e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-clause : [C++ class.derived]
1424e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ':' base-specifier-list
1425e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier-list:
1426e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier '...'[opt]
1427e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier-list ',' base-specifier '...'[opt]
1428d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseBaseClause(Decl *ClassDecl) {
1429e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  assert(Tok.is(tok::colon) && "Not a base clause");
1430e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  ConsumeToken();
1431e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1432f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Build up an array of parsed base specifiers.
14335f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<CXXBaseSpecifier *, 8> BaseInfo;
1434f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
1435e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  while (true) {
1436e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Parse a base-specifier.
1437f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    BaseResult Result = ParseBaseSpecifier(ClassDecl);
14385ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor    if (Result.isInvalid()) {
1439e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Skip the rest of this base specifier, up until the comma or
1440e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // opening brace.
1441f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      SkipUntil(tok::comma, tok::l_brace, true, true);
1442f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    } else {
1443f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      // Add this to our array of base specifiers.
14445ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor      BaseInfo.push_back(Result.get());
1445e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
1446e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1447e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // If the next token is a comma, consume it and keep reading
1448e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // base-specifiers.
1449e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (Tok.isNot(tok::comma)) break;
14501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1451e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Consume the comma.
1452e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
1453e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1454f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
1455f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Attach the base specifiers
1456beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad  Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size());
1457e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1458e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1459e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
1460e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example:
1461e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///    class foo : public bar, virtual private baz {
1462e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers.
1463e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1464e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier: [C++ class.derived]
1465e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ::[opt] nested-name-specifier[opt] class-name
1466e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt]
146709048df0b3f472091b2204e531d6b6019244884bDavid Blaikie///                        base-type-specifier
1468e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
146909048df0b3f472091b2204e531d6b6019244884bDavid Blaikie///                        base-type-specifier
1470d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {
1471e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  bool IsVirtual = false;
1472e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation StartLoc = Tok.getLocation();
1473e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1474e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword.
1475e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
1476e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
1477e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
1478e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1479e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1480e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse an (optional) access specifier.
1481e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  AccessSpecifier Access = getAccessSpecifierIfPresent();
148292f883177b162928a8e632e4e3b93fafd2b26072John McCall  if (Access != AS_none)
1483e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
14841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1485e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword (again!), in case it came after the
1486e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // access specifier.
1487e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
1488e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SourceLocation VirtualLoc = ConsumeToken();
1489e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (IsVirtual) {
1490e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Complain about duplicate 'virtual'
14911ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner      Diag(VirtualLoc, diag::err_dup_virtual)
1492849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor        << FixItHint::CreateRemoval(VirtualLoc);
1493e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
1494e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1495e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
1496e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1497e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
149842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Parse the class-name.
14997f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceLocation EndLocation;
150022216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie  SourceLocation BaseLoc;
150122216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie  TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation);
150231a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor  if (BaseType.isInvalid())
150342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor    return true;
15041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1505f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // Parse the optional ellipsis (for a pack expansion). The ellipsis is
1506f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // actually part of the base-specifier-list grammar productions, but we
1507f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // parse it here for convenience.
1508f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  SourceLocation EllipsisLoc;
1509f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  if (Tok.is(tok::ellipsis))
1510f90b27ad077c3339b62befc892382845339f9490Douglas Gregor    EllipsisLoc = ConsumeToken();
1511f90b27ad077c3339b62befc892382845339f9490Douglas Gregor
15121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Find the complete source range for the base-specifier.
15137f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceRange Range(StartLoc, EndLocation);
15141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1515e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Notify semantic analysis that we have parsed a complete
1516e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // base-specifier.
1517a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl  return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
1518f90b27ad077c3339b62befc892382845339f9490Douglas Gregor                                    BaseType.get(), BaseLoc, EllipsisLoc);
1519e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1520e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1521e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is
1522e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier.
1523e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1524e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       access-specifier: [C++ class.derived]
1525e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'private'
1526e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'protected'
1527e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'public'
15281eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAccessSpecifier Parser::getAccessSpecifierIfPresent() const {
1529e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  switch (Tok.getKind()) {
1530e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  default: return AS_none;
1531e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_private: return AS_private;
1532e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_protected: return AS_protected;
1533e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_public: return AS_public;
1534e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1535e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
15364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
153774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor/// \brief If the given declarator has any parts for which parsing has to be
153874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor/// delayed, e.g., default arguments or an exception-specification, create a
153974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor/// late-parsed method declaration record to handle the parsing at the end of
154074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor/// the class definition.
154174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregorvoid Parser::HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
154274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                                            Decl *ThisDecl) {
1543d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // We just declared a member function. If this member function
154474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  // has any default arguments or an exception-specification, we'll need to
154574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  // parse them later.
1546d33133cdc1af466f9c276249b2621be03867888bEli Friedman  LateParsedMethodDeclaration *LateMethod = 0;
15471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  DeclaratorChunk::FunctionTypeInfo &FTI
1548075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara    = DeclaratorInfo.getFunctionTypeInfo();
154974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
155074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  // If there was a delayed exception-specification, hold onto its tokens.
155174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  if (FTI.getExceptionSpecType() == EST_Delayed) {
155274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Push this method onto the stack of late-parsed method
155374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // declarations.
155474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
155574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
155674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    LateMethod->TemplateScope = getCurScope()->isTemplateParamScope();
155774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
155874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Stash the exception-specification tokens in the late-pased mthod.
155974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens;
156074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    FTI.ExceptionSpecTokens = 0;
156174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
156274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Reserve space for the parameters.
156374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    LateMethod->DefaultArgs.reserve(FTI.NumArgs);
156474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  }
156574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
1566d33133cdc1af466f9c276249b2621be03867888bEli Friedman  for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
1567d33133cdc1af466f9c276249b2621be03867888bEli Friedman    if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
1568d33133cdc1af466f9c276249b2621be03867888bEli Friedman      if (!LateMethod) {
1569d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Push this method onto the stack of late-parsed method
1570d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // declarations.
1571d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
1572d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
157323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        LateMethod->TemplateScope = getCurScope()->isTemplateParamScope();
1574d33133cdc1af466f9c276249b2621be03867888bEli Friedman
1575d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Add all of the parameters prior to this one (they don't
1576d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // have default arguments).
1577d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateMethod->DefaultArgs.reserve(FTI.NumArgs);
1578d33133cdc1af466f9c276249b2621be03867888bEli Friedman        for (unsigned I = 0; I < ParamIdx; ++I)
1579d33133cdc1af466f9c276249b2621be03867888bEli Friedman          LateMethod->DefaultArgs.push_back(
15808f8210c47797f013e0fb24a26f9c4751b10783feDouglas Gregor                             LateParsedDefaultArgument(FTI.ArgInfo[I].Param));
1581d33133cdc1af466f9c276249b2621be03867888bEli Friedman      }
1582d33133cdc1af466f9c276249b2621be03867888bEli Friedman
158374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      // Add this parameter to the list of parameters (it may or may
1584d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // not have a default argument).
1585d33133cdc1af466f9c276249b2621be03867888bEli Friedman      LateMethod->DefaultArgs.push_back(
1586d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
1587d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                  FTI.ArgInfo[ParamIdx].DefaultArgTokens));
1588d33133cdc1af466f9c276249b2621be03867888bEli Friedman    }
1589d33133cdc1af466f9c276249b2621be03867888bEli Friedman  }
1590d33133cdc1af466f9c276249b2621be03867888bEli Friedman}
1591d33133cdc1af466f9c276249b2621be03867888bEli Friedman
15921c94c16317c1a35c1549e022958188eea2567089Richard Smith/// isCXX0XVirtSpecifier - Determine whether the given token is a C++0x
15931f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier.
15941f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
15951f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier:
15961f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         override
15971f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         final
15981c94c16317c1a35c1549e022958188eea2567089Richard SmithVirtSpecifiers::Specifier Parser::isCXX0XVirtSpecifier(const Token &Tok) const {
15994e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!getLangOpts().CPlusPlus)
1600cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson    return VirtSpecifiers::VS_None;
1601cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
1602b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  if (Tok.is(tok::identifier)) {
1603b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    IdentifierInfo *II = Tok.getIdentifierInfo();
16041f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
16057eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    // Initialize the contextual keywords.
16067eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    if (!Ident_final) {
16077eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson      Ident_final = &PP.getIdentifierTable().get("final");
16087eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson      Ident_override = &PP.getIdentifierTable().get("override");
16097eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    }
16107eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson
1611b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (II == Ident_override)
1612b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return VirtSpecifiers::VS_Override;
16131f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
1614b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (II == Ident_final)
1615b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return VirtSpecifiers::VS_Final;
1616b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  }
1617b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
1618b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  return VirtSpecifiers::VS_None;
16191f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson}
16201f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
16211f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// ParseOptionalCXX0XVirtSpecifierSeq - Parse a virt-specifier-seq.
16221f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
16231f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier-seq:
16241f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier
16251f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier-seq virt-specifier
1626b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlssonvoid Parser::ParseOptionalCXX0XVirtSpecifierSeq(VirtSpecifiers &VS) {
1627b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  while (true) {
1628cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson    VirtSpecifiers::Specifier Specifier = isCXX0XVirtSpecifier();
1629b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (Specifier == VirtSpecifiers::VS_None)
1630b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return;
1631b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
1632b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    // C++ [class.mem]p8:
1633b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    //   A virt-specifier-seq shall contain at most one of each virt-specifier.
1634cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson    const char *PrevSpec = 0;
163546127a96b6dd6b93aa18d5f7a55bc2db8b52a2c9Anders Carlsson    if (VS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec))
1636b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier)
1637b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson        << PrevSpec
1638b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson        << FixItHint::CreateRemoval(Tok.getLocation());
1639b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
16404e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    Diag(Tok.getLocation(), getLangOpts().CPlusPlus0x ?
16417fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith         diag::warn_cxx98_compat_override_control_keyword :
16427fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith         diag::ext_override_control_keyword)
16437fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith      << VirtSpecifiers::getSpecifierName(Specifier);
1644b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    ConsumeToken();
1645b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  }
16461f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson}
16471f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
16488a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson/// isCXX0XFinalKeyword - Determine whether the next token is a C++0x
16498a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson/// contextual 'final' keyword.
16508a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlssonbool Parser::isCXX0XFinalKeyword() const {
16514e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!getLangOpts().CPlusPlus)
16528a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    return false;
1653cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
16548a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  if (!Tok.is(tok::identifier))
16558a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    return false;
1656cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
16578a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  // Initialize the contextual keywords.
16588a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  if (!Ident_final) {
16598a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    Ident_final = &PP.getIdentifierTable().get("final");
16608a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    Ident_override = &PP.getIdentifierTable().get("override");
1661cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson  }
16628a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson
16638a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  return Tok.getIdentifierInfo() == Ident_final;
1664cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson}
1665cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
16664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
16674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
16684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declaration:
16694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         decl-specifier-seq[opt] member-declarator-list[opt] ';'
16704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         function-definition ';'[opt]
16714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
16724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         using-declaration                                            [TODO]
1673511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration
16745aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson///         template-declaration
1675bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU]   '__extension__' member-declaration
16764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
16774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator-list:
16784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator
16794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator-list ',' member-declarator
16804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
16814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator:
16821f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         declarator virt-specifier-seq[opt] pure-specifier[opt]
16834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         declarator constant-initializer[opt]
16847a614d8380297fcd2bc23986241905d97222948cRichard Smith/// [C++11] declarator brace-or-equal-initializer[opt]
16854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         identifier[opt] ':' constant-expression
16864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
16871f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier-seq:
16881f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier
16891f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier-seq virt-specifier
16901f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
16911f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier:
16921f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         override
16931f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         final
16941f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
1695e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl///       pure-specifier:
16964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '= 0'
16974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
16984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       constant-initializer:
16994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '=' constant-expression
17004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
170137b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregorvoid Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
17025f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                            AttributeList *AccessAttrs,
1703c9068d7dd94d439cec66c421115d15303e481025John McCall                                       const ParsedTemplateInfo &TemplateInfo,
1704c9068d7dd94d439cec66c421115d15303e481025John McCall                                       ParsingDeclRAIIObject *TemplateDiags) {
17058a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor  if (Tok.is(tok::at)) {
17064e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().ObjC1 && NextToken().isObjCAtKeyword(tok::objc_defs))
17078a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor      Diag(Tok, diag::err_at_defs_cxx);
17088a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    else
17098a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor      Diag(Tok, diag::err_at_in_class);
17108a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor
17118a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    ConsumeToken();
17128a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    SkipUntil(tok::r_brace);
17138a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    return;
17148a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor  }
17158a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor
171660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  // Access declarations.
171760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  if (!TemplateInfo.Kind &&
171860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) &&
17199ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall      !TryAnnotateCXXScopeToken() &&
172060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      Tok.is(tok::annot_cxxscope)) {
172160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    bool isAccessDecl = false;
172260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    if (NextToken().is(tok::identifier))
172360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      isAccessDecl = GetLookAheadToken(2).is(tok::semi);
172460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    else
172560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      isAccessDecl = NextToken().is(tok::kw_operator);
172660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
172760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    if (isAccessDecl) {
172860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // Collect the scope specifier token we annotated earlier.
172960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      CXXScopeSpec SS;
1730efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor      ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
1731efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor                                     /*EnteringContext=*/false);
173260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
173360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // Try to parse an unqualified-id.
1734e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara      SourceLocation TemplateKWLoc;
173560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      UnqualifiedId Name;
1736e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara      if (ParseUnqualifiedId(SS, false, true, true, ParsedType(),
1737e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                             TemplateKWLoc, Name)) {
173860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        SkipUntil(tok::semi);
173960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        return;
174060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      }
174160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
174260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // TODO: recover from mistakenly-qualified operator declarations.
174360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      if (ExpectAndConsume(tok::semi,
174460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           diag::err_expected_semi_after,
174560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           "access declaration",
174660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           tok::semi))
174760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        return;
174860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
174923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.ActOnUsingDeclaration(getCurScope(), AS,
175060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    false, SourceLocation(),
175160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    SS, Name,
175260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    /* AttrList */ 0,
175360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    /* IsTypeName */ false,
175460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    SourceLocation());
175560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      return;
175660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    }
175760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  }
175860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
1759511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  // static_assert-declaration
1760c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne  if (Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) {
176137b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    // FIXME: Check for templates
176297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
176397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    ParseStaticAssertDeclaration(DeclEnd);
1764682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1765682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
17661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1767682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  if (Tok.is(tok::kw_template)) {
17681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(!TemplateInfo.TemplateParams &&
176937b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor           "Nested template improperly parsed?");
177097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
17711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd,
17725f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                         AS, AccessAttrs);
1773682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1774682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
17755aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson
1776bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  // Handle:  member-declaration ::= '__extension__' member-declaration
1777bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  if (Tok.is(tok::kw___extension__)) {
1778bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    // __extension__ silences extension warnings in the subexpression.
1779bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
1780bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ConsumeToken();
17815f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    return ParseCXXClassMemberDeclaration(AS, AccessAttrs,
17825f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                          TemplateInfo, TemplateDiags);
1783bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  }
17849cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
17854ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it
17864ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // is a bitfield.
1787a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner  ColonProtectionRAIIObject X(*this);
1788193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
17890b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributesWithRange attrs(AttrFactory);
1790bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // Optional C++0x attribute-specifier
17917f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseCXX0XAttributes(attrs);
17927f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseMicrosoftAttributes(attrs);
1793bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
17949cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_using)) {
17957f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ProhibitAttributes(attrs);
17961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17979cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    // Eat 'using'.
17989cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SourceLocation UsingLoc = ConsumeToken();
17999cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
18009cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    if (Tok.is(tok::kw_namespace)) {
18019cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      Diag(UsingLoc, diag::err_using_namespace_in_class);
18029cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SkipUntil(tok::semi, true, true);
1803ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    } else {
18049cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SourceLocation DeclEnd;
18053e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      // Otherwise, it must be a using-declaration or an alias-declaration.
180678b810559d89e996e00684335407443936ce34a1John McCall      ParseUsingDeclaration(Declarator::MemberContext, TemplateInfo,
180778b810559d89e996e00684335407443936ce34a1John McCall                            UsingLoc, DeclEnd, AS);
18089cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    }
18099cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return;
18109cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
18119cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
18122287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  // Hold late-parsed attributes so we can attach a Decl to them later.
18132287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  LateParsedAttrList CommonLateParsedAttrs;
18142287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
18154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // decl-specifier-seq:
18164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Parse the common declaration-specifiers piece.
1817c9068d7dd94d439cec66c421115d15303e481025John McCall  ParsingDeclSpec DS(*this, TemplateDiags);
18187f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  DS.takeAttributesFrom(attrs);
18192287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class,
18202287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins                             &CommonLateParsedAttrs);
18214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1822f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  MultiTemplateParamsArg TemplateParams(Actions,
1823dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
1824dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
1825dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
18264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::semi)) {
18274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
1828d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decl *TheDecl =
18290f4be74ff0273e505d383f89174ef539828424edChandler Carruth      Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS, TemplateParams);
1830c9068d7dd94d439cec66c421115d15303e481025John McCall    DS.complete(TheDecl);
183167d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    return;
18324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
183307952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
183454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext);
18354867347e82648d3baf09524b98b09c297a5a198fNico Weber  VirtSpecifiers VS;
18364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1837eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  // Hold late-parsed attributes so we can attach a Decl to them later.
1838eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  LateParsedAttrList LateParsedAttrs;
1839eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
1840a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor  SourceLocation EqualLoc;
1841a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor  bool HasInitializer = false;
1842a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor  ExprResult Init;
18433a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis  if (Tok.isNot(tok::colon)) {
1844a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner    // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
1845a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner    ColonProtectionRAIIObject X(*this);
1846a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner
18473a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Parse the first declarator.
18483a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    ParseDeclarator(DeclaratorInfo);
184974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Error parsin g the declarator?
185010bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor    if (!DeclaratorInfo.hasName()) {
18513a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      // If so, skip until the semi-colon or a }.
1852d941fa4ff0d0d64b5a541dbd4f99693bff7f6e8dSebastian Redl      SkipUntil(tok::r_brace, true, true);
18533a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (Tok.is(tok::semi))
18543a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeToken();
1855682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
18564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
18574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
18584867347e82648d3baf09524b98b09c297a5a198fNico Weber    ParseOptionalCXX0XVirtSpecifierSeq(VS);
18594867347e82648d3baf09524b98b09c297a5a198fNico Weber
18601b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson    // If attributes exist after the declarator, but before an '{', parse them.
1861eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
18621b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson
18636a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    // MSVC permits pure specifier on inline functions declared at class scope.
18646a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    // Hence check for =0 before checking for function definition.
18654e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().MicrosoftExt && Tok.is(tok::equal) &&
18666a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        DeclaratorInfo.isFunctionDeclarator() &&
18676a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        NextToken().is(tok::numeric_constant)) {
1868a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor      EqualLoc = ConsumeToken();
18696a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet      Init = ParseInitializer();
18706a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet      if (Init.isInvalid())
18716a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        SkipUntil(tok::comma, true, true);
1872a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor      else
1873a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor        HasInitializer = true;
18746a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    }
18756a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet
187645fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor    FunctionDefinitionKind DefinitionKind = FDK_Declaration;
18773a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // function-definition:
18787a614d8380297fcd2bc23986241905d97222948cRichard Smith    //
18797a614d8380297fcd2bc23986241905d97222948cRichard Smith    // In C++11, a non-function declarator followed by an open brace is a
18807a614d8380297fcd2bc23986241905d97222948cRichard Smith    // braced-init-list for an in-class member initialization, not an
18817a614d8380297fcd2bc23986241905d97222948cRichard Smith    // erroneous function definition.
18824e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (Tok.is(tok::l_brace) && !getLangOpts().CPlusPlus0x) {
188345fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor      DefinitionKind = FDK_Definition;
1884e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    } else if (DeclaratorInfo.isFunctionDeclarator()) {
18857a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
188645fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor        DefinitionKind = FDK_Definition;
1887e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      } else if (Tok.is(tok::equal)) {
1888e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        const Token &KW = NextToken();
188945fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor        if (KW.is(tok::kw_default))
189045fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor          DefinitionKind = FDK_Defaulted;
189145fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor        else if (KW.is(tok::kw_delete))
189245fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor          DefinitionKind = FDK_Deleted;
1893e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      }
1894e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    }
1895e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
189645fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor    if (DefinitionKind) {
18973a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (!DeclaratorInfo.isFunctionDeclarator()) {
189865ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu        Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params);
18993a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
190065ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu        SkipUntil(tok::r_brace, /*StopAtSemi*/false);
19019ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor
19029ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        // Consume the optional ';'
19039ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        if (Tok.is(tok::semi))
19049ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor          ConsumeToken();
1905682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
19063a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
19073a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis
19083a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
190965ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu        Diag(DeclaratorInfo.getIdentifierLoc(),
191065ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu             diag::err_function_declared_typedef);
19113a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // This recovery skips the entire function body. It would be nice
19123a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // to simply call ParseCXXInlineMethodDef() below, however Sema
19133a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // assumes the declarator represents a function, not a typedef.
19143a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
191565ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu        SkipUntil(tok::r_brace, /*StopAtSemi*/false);
19169ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor
19179ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        // Consume the optional ';'
19189ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        if (Tok.is(tok::semi))
19199ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor          ConsumeToken();
1920682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
19213a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
19224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1923eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      Decl *FunDecl =
19245f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen        ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo, TemplateInfo,
192545fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor                                VS, DefinitionKind, Init);
1926eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
19272287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
19282287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins        CommonLateParsedAttrs[i]->addDecl(FunDecl);
19292287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      }
1930eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
19312287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins        LateParsedAttrs[i]->addDecl(FunDecl);
1932eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      }
1933eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      LateParsedAttrs.clear();
1934e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
1935e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      // Consume the ';' - it's optional unless we have a delete or default
1936e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      if (Tok.is(tok::semi)) {
19379ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        ConsumeToken();
1938e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      }
19399ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor
1940682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
19413a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    }
19424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
19434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
19444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // member-declarator-list:
19454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator
19464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator-list ',' member-declarator
19474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
19485f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Decl *, 8> DeclsInGroup;
194960d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult BitfieldSize;
19501c94c16317c1a35c1549e022958188eea2567089Richard Smith  bool ExpectSemi = true;
19514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
19524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  while (1) {
19534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // member-declarator:
19544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   declarator pure-specifier[opt]
19557a614d8380297fcd2bc23986241905d97222948cRichard Smith    //   declarator brace-or-equal-initializer[opt]
19564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   identifier[opt] ':' constant-expression
19574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::colon)) {
19584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
19590e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      BitfieldSize = ParseConstantExpression();
19600e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      if (BitfieldSize.isInvalid())
19614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        SkipUntil(tok::comma, true, true);
19624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
19631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1964e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    // If a simple-asm-expr is present, parse it.
1965e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    if (Tok.is(tok::kw_asm)) {
1966e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      SourceLocation Loc;
196760d7b3a319d84d688752be3870615ac0f111fb16John McCall      ExprResult AsmLabel(ParseSimpleAsm(&Loc));
1968e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      if (AsmLabel.isInvalid())
1969e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner        SkipUntil(tok::comma, true, true);
1970e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner
1971e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      DeclaratorInfo.setAsmLabel(AsmLabel.release());
1972e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      DeclaratorInfo.SetRangeEnd(Loc);
1973e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    }
1974e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner
19754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If attributes exist after the declarator, parse them.
1976eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
19774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
19787a614d8380297fcd2bc23986241905d97222948cRichard Smith    // FIXME: When g++ adds support for this, we'll need to check whether it
19797a614d8380297fcd2bc23986241905d97222948cRichard Smith    // goes before or after the GNU attributes and __asm__.
19807a614d8380297fcd2bc23986241905d97222948cRichard Smith    ParseOptionalCXX0XVirtSpecifierSeq(VS);
19817a614d8380297fcd2bc23986241905d97222948cRichard Smith
19827a614d8380297fcd2bc23986241905d97222948cRichard Smith    bool HasDeferredInitializer = false;
1983a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor    if ((Tok.is(tok::equal) || Tok.is(tok::l_brace)) && !HasInitializer) {
19847a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (BitfieldSize.get()) {
19857a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(Tok, diag::err_bitfield_member_init);
19867a614d8380297fcd2bc23986241905d97222948cRichard Smith        SkipUntil(tok::comma, true, true);
19877a614d8380297fcd2bc23986241905d97222948cRichard Smith      } else {
1988147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor        HasInitializer = true;
1989555f57e3549fb5cc963a2ce38180c4f3643a6f95Douglas Gregor        HasDeferredInitializer = !DeclaratorInfo.isDeclarationOfFunction() &&
19907a614d8380297fcd2bc23986241905d97222948cRichard Smith          DeclaratorInfo.getDeclSpec().getStorageClassSpec()
1991c2cdd5354aba8d6a74c45231829f3bbbbfeb2781Richard Smith            != DeclSpec::SCS_static &&
1992c2cdd5354aba8d6a74c45231829f3bbbbfeb2781Richard Smith          DeclaratorInfo.getDeclSpec().getStorageClassSpec()
1993c2cdd5354aba8d6a74c45231829f3bbbbfeb2781Richard Smith            != DeclSpec::SCS_typedef;
19947a614d8380297fcd2bc23986241905d97222948cRichard Smith      }
19957a614d8380297fcd2bc23986241905d97222948cRichard Smith    }
19967a614d8380297fcd2bc23986241905d97222948cRichard Smith
199707952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // NOTE: If Sema is the Action module and declarator is an instance field,
1998682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    // this call will *not* return the created decl; It will return null.
199907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // See Sema::ActOnCXXMemberDeclarator for details.
200067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall
2001d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decl *ThisDecl = 0;
200267d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    if (DS.isFriendSpecified()) {
2003bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall      // TODO: handle initializers, bitfields, 'delete'
200423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo,
2005bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall                                                 move(TemplateParams));
200637b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    } else {
200723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS,
200867d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  DeclaratorInfo,
200937b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor                                                  move(TemplateParams),
201067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  BitfieldSize.release(),
20112c712f50cd56eaf3662989b556e9c6b1e8fcd11aKaelyn Uhrain                                                  VS, HasDeferredInitializer);
20125f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      if (AccessAttrs)
20135f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen        Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs,
20145f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                         false, true);
201537b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    }
2016147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor
2017eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    // Set the Decl for any late parsed attributes
20182287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
20192287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      CommonLateParsedAttrs[i]->addDecl(ThisDecl);
20202287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    }
2021eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
20222287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      LateParsedAttrs[i]->addDecl(ThisDecl);
2023eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    }
2024eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    LateParsedAttrs.clear();
2025eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
2026147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    // Handle the initializer.
20277a614d8380297fcd2bc23986241905d97222948cRichard Smith    if (HasDeferredInitializer) {
2028147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      // The initializer was deferred; parse it and cache the tokens.
20294e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      Diag(Tok, getLangOpts().CPlusPlus0x ?
20307fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith           diag::warn_cxx98_compat_nonstatic_member_init :
20317fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith           diag::ext_nonstatic_member_init);
20327fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith
20337a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (DeclaratorInfo.isArrayOfUnknownBound()) {
20347a614d8380297fcd2bc23986241905d97222948cRichard Smith        // C++0x [dcl.array]p3: An array bound may also be omitted when the
20357a614d8380297fcd2bc23986241905d97222948cRichard Smith        // declarator is followed by an initializer.
20367a614d8380297fcd2bc23986241905d97222948cRichard Smith        //
20377a614d8380297fcd2bc23986241905d97222948cRichard Smith        // A brace-or-equal-initializer for a member-declarator is not an
20383164c14cadbb09a05ba811602221e9156077cf44David Blaikie        // initializer in the grammar, so this is ill-formed.
20397a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(Tok, diag::err_incomplete_array_member_init);
20407a614d8380297fcd2bc23986241905d97222948cRichard Smith        SkipUntil(tok::comma, true, true);
20413164c14cadbb09a05ba811602221e9156077cf44David Blaikie        if (ThisDecl)
20423164c14cadbb09a05ba811602221e9156077cf44David Blaikie          // Avoid later warnings about a class member of incomplete type.
20433164c14cadbb09a05ba811602221e9156077cf44David Blaikie          ThisDecl->setInvalidDecl();
20447a614d8380297fcd2bc23986241905d97222948cRichard Smith      } else
20457a614d8380297fcd2bc23986241905d97222948cRichard Smith        ParseCXXNonStaticMemberInitializer(ThisDecl);
2046147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    } else if (HasInitializer) {
2047147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      // Normal initializer.
2048a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor      if (!Init.isUsable())
2049552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor        Init = ParseCXXMemberInitializer(ThisDecl,
2050a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor                 DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
2051a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor
2052147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      if (Init.isInvalid())
2053147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor        SkipUntil(tok::comma, true, true);
2054147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      else if (ThisDecl)
205533deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl        Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid(),
2056a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor                                   DS.getTypeSpecType() == DeclSpec::TST_auto);
2057147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static) {
2058147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      // No initializer.
2059147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      Actions.ActOnUninitializedDecl(ThisDecl,
2060147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor                                   DS.getTypeSpecType() == DeclSpec::TST_auto);
20617a614d8380297fcd2bc23986241905d97222948cRichard Smith    }
2062147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor
2063147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    if (ThisDecl) {
2064147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      Actions.FinalizeDeclaration(ThisDecl);
2065147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      DeclsInGroup.push_back(ThisDecl);
2066147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    }
2067147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor
2068147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    if (DeclaratorInfo.isFunctionDeclarator() &&
2069147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor        DeclaratorInfo.getDeclSpec().getStorageClassSpec()
2070147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor          != DeclSpec::SCS_typedef) {
207174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
2072147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    }
2073147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor
2074147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    DeclaratorInfo.complete(ThisDecl);
20757a614d8380297fcd2bc23986241905d97222948cRichard Smith
20764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If we don't have a comma, it is either the end of the list (a ';')
20774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // or an error, bail out.
20784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.isNot(tok::comma))
20794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
20801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Consume the comma.
20821c94c16317c1a35c1549e022958188eea2567089Richard Smith    SourceLocation CommaLoc = ConsumeToken();
20831c94c16317c1a35c1549e022958188eea2567089Richard Smith
20841c94c16317c1a35c1549e022958188eea2567089Richard Smith    if (Tok.isAtStartOfLine() &&
20851c94c16317c1a35c1549e022958188eea2567089Richard Smith        !MightBeDeclarator(Declarator::MemberContext)) {
20861c94c16317c1a35c1549e022958188eea2567089Richard Smith      // This comma was followed by a line-break and something which can't be
20871c94c16317c1a35c1549e022958188eea2567089Richard Smith      // the start of a declarator. The comma was probably a typo for a
20881c94c16317c1a35c1549e022958188eea2567089Richard Smith      // semicolon.
20891c94c16317c1a35c1549e022958188eea2567089Richard Smith      Diag(CommaLoc, diag::err_expected_semi_declaration)
20901c94c16317c1a35c1549e022958188eea2567089Richard Smith        << FixItHint::CreateReplacement(CommaLoc, ";");
20911c94c16317c1a35c1549e022958188eea2567089Richard Smith      ExpectSemi = false;
20921c94c16317c1a35c1549e022958188eea2567089Richard Smith      break;
20931c94c16317c1a35c1549e022958188eea2567089Richard Smith    }
20941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Parse the next declarator.
20964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    DeclaratorInfo.clear();
20974867347e82648d3baf09524b98b09c297a5a198fNico Weber    VS.clear();
2098147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    BitfieldSize = true;
2099a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor    Init = true;
2100a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor    HasInitializer = false;
21017984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith    DeclaratorInfo.setCommaLoc(CommaLoc);
21021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Attributes are only allowed on the second declarator.
21047f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseGNUAttributes(DeclaratorInfo);
21054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
21063a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    if (Tok.isNot(tok::colon))
21073a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      ParseDeclarator(DeclaratorInfo);
21084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
21094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
21101c94c16317c1a35c1549e022958188eea2567089Richard Smith  if (ExpectSemi &&
21111c94c16317c1a35c1549e022958188eea2567089Richard Smith      ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
2112ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    // Skip to end of block or statement.
2113ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    SkipUntil(tok::r_brace, true, true);
2114ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    // If we stopped at a ';', eat it.
2115ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    if (Tok.is(tok::semi)) ConsumeToken();
2116682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
21174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
21184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
211923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup.data(),
2120ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner                                  DeclsInGroup.size());
21214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
21224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
21237a614d8380297fcd2bc23986241905d97222948cRichard Smith/// ParseCXXMemberInitializer - Parse the brace-or-equal-initializer or
21247a614d8380297fcd2bc23986241905d97222948cRichard Smith/// pure-specifier. Also detect and reject any attempted defaulted/deleted
21257a614d8380297fcd2bc23986241905d97222948cRichard Smith/// function definition. The location of the '=', if any, will be placed in
21267a614d8380297fcd2bc23986241905d97222948cRichard Smith/// EqualLoc.
21277a614d8380297fcd2bc23986241905d97222948cRichard Smith///
21287a614d8380297fcd2bc23986241905d97222948cRichard Smith///   pure-specifier:
21297a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '= 0'
213033deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///
21317a614d8380297fcd2bc23986241905d97222948cRichard Smith///   brace-or-equal-initializer:
21327a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '=' initializer-expression
213333deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///     braced-init-list
213433deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///
21357a614d8380297fcd2bc23986241905d97222948cRichard Smith///   initializer-clause:
21367a614d8380297fcd2bc23986241905d97222948cRichard Smith///     assignment-expression
213733deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///     braced-init-list
213833deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///
21397a614d8380297fcd2bc23986241905d97222948cRichard Smith///   defaulted/deleted function-definition:
21407a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '=' 'default'
21417a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '=' 'delete'
21427a614d8380297fcd2bc23986241905d97222948cRichard Smith///
21437a614d8380297fcd2bc23986241905d97222948cRichard Smith/// Prior to C++0x, the assignment-expression in an initializer-clause must
21447a614d8380297fcd2bc23986241905d97222948cRichard Smith/// be a constant-expression.
2145552e29985a710f4ced62b39d70557501bd31ca9bDouglas GregorExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,
21467a614d8380297fcd2bc23986241905d97222948cRichard Smith                                             SourceLocation &EqualLoc) {
21477a614d8380297fcd2bc23986241905d97222948cRichard Smith  assert((Tok.is(tok::equal) || Tok.is(tok::l_brace))
21487a614d8380297fcd2bc23986241905d97222948cRichard Smith         && "Data member initializer not starting with '=' or '{'");
21497a614d8380297fcd2bc23986241905d97222948cRichard Smith
2150552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor  EnterExpressionEvaluationContext Context(Actions,
2151552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor                                           Sema::PotentiallyEvaluated,
2152552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor                                           D);
21537a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (Tok.is(tok::equal)) {
21547a614d8380297fcd2bc23986241905d97222948cRichard Smith    EqualLoc = ConsumeToken();
21557a614d8380297fcd2bc23986241905d97222948cRichard Smith    if (Tok.is(tok::kw_delete)) {
21567a614d8380297fcd2bc23986241905d97222948cRichard Smith      // In principle, an initializer of '= delete p;' is legal, but it will
21577a614d8380297fcd2bc23986241905d97222948cRichard Smith      // never type-check. It's better to diagnose it as an ill-formed expression
21587a614d8380297fcd2bc23986241905d97222948cRichard Smith      // than as an ill-formed deleted non-function member.
21597a614d8380297fcd2bc23986241905d97222948cRichard Smith      // An initializer of '= delete p, foo' will never be parsed, because
21607a614d8380297fcd2bc23986241905d97222948cRichard Smith      // a top-level comma always ends the initializer expression.
21617a614d8380297fcd2bc23986241905d97222948cRichard Smith      const Token &Next = NextToken();
21627a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (IsFunction || Next.is(tok::semi) || Next.is(tok::comma) ||
21637a614d8380297fcd2bc23986241905d97222948cRichard Smith           Next.is(tok::eof)) {
21647a614d8380297fcd2bc23986241905d97222948cRichard Smith        if (IsFunction)
21657a614d8380297fcd2bc23986241905d97222948cRichard Smith          Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
21667a614d8380297fcd2bc23986241905d97222948cRichard Smith            << 1 /* delete */;
21677a614d8380297fcd2bc23986241905d97222948cRichard Smith        else
21687a614d8380297fcd2bc23986241905d97222948cRichard Smith          Diag(ConsumeToken(), diag::err_deleted_non_function);
21697a614d8380297fcd2bc23986241905d97222948cRichard Smith        return ExprResult();
21707a614d8380297fcd2bc23986241905d97222948cRichard Smith      }
21717a614d8380297fcd2bc23986241905d97222948cRichard Smith    } else if (Tok.is(tok::kw_default)) {
21727a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (IsFunction)
21737a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(Tok, diag::err_default_delete_in_multiple_declaration)
21747a614d8380297fcd2bc23986241905d97222948cRichard Smith          << 0 /* default */;
21757a614d8380297fcd2bc23986241905d97222948cRichard Smith      else
21767a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(ConsumeToken(), diag::err_default_special_members);
21777a614d8380297fcd2bc23986241905d97222948cRichard Smith      return ExprResult();
21787a614d8380297fcd2bc23986241905d97222948cRichard Smith    }
21797a614d8380297fcd2bc23986241905d97222948cRichard Smith
218033deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl  }
218133deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl  return ParseInitializer();
21827a614d8380297fcd2bc23986241905d97222948cRichard Smith}
21837a614d8380297fcd2bc23986241905d97222948cRichard Smith
21844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition.
21854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
21864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-specification:
21874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declaration member-specification[opt]
21884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         access-specifier ':' member-specification[opt]
21894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
21904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidisvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
2191d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall                                         unsigned TagType, Decl *TagDecl) {
219231fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta  assert((TagType == DeclSpec::TST_struct ||
21934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis         TagType == DeclSpec::TST_union  ||
219431fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta         TagType == DeclSpec::TST_class) && "Invalid TagType!");
21954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
2196f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
2197f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing struct/union/class body");
21981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
219926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  // Determine whether this is a non-nested class. Note that local
220026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  // classes are *not* considered to be nested classes.
220126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  bool NonNestedClass = true;
220226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  if (!ClassStack.empty()) {
220323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    for (const Scope *S = getCurScope(); S; S = S->getParent()) {
220426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      if (S->isClassScope()) {
220526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // We're inside a class scope, so this is a nested class.
220626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        NonNestedClass = false;
220726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        break;
220826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      }
220926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor
221026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      if ((S->getFlags() & Scope::FnScope)) {
221126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // If we're in a function or function template declared in the
221226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // body of a class, then this is a local class rather than a
221326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // nested class.
221426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        const Scope *Parent = S->getParent();
221526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        if (Parent->isTemplateParamScope())
221626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor          Parent = Parent->getParent();
221726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        if (Parent->isClassScope())
221826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor          break;
221926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      }
222026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor    }
222126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  }
22224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
22234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Enter a scope for the class.
22243218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
22254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
22266569d68745c8213709740337d2be52b031384f58Douglas Gregor  // Note that we are parsing a new (potentially-nested) class definition.
222726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass);
22286569d68745c8213709740337d2be52b031384f58Douglas Gregor
2229ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  if (TagDecl)
223023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
2231bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
2232b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  SourceLocation FinalLoc;
2233b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson
2234b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  // Parse the optional 'final' keyword.
22354e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) {
22368b11b5e6ce086fcaa7344bf84cffefcf4b53f9f6Richard Smith    assert(isCXX0XFinalKeyword() && "not a class definition");
22378b11b5e6ce086fcaa7344bf84cffefcf4b53f9f6Richard Smith    FinalLoc = ConsumeToken();
2238b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson
22394e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    Diag(FinalLoc, getLangOpts().CPlusPlus0x ?
22407fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith         diag::warn_cxx98_compat_override_control_keyword :
22417fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith         diag::ext_override_control_keyword) << "final";
2242b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  }
2243cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
2244bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  if (Tok.is(tok::colon)) {
2245bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    ParseBaseClause(TagDecl);
2246bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
2247bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    if (!Tok.is(tok::l_brace)) {
2248bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall      Diag(Tok, diag::err_expected_lbrace_after_base_specifiers);
2249db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall
2250db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall      if (TagDecl)
225123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);
2252bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall      return;
2253bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    }
2254bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  }
2255bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
2256bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  assert(Tok.is(tok::l_brace));
22574a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_brace);
22584a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
2259bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
226042a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
22612c3ee54e51d835a35bbf781c69e17f39e2ba0480Anders Carlsson    Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc,
22624a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                            T.getOpenLocation());
2263f9368159334ff86ea5fa367225c1a580977f3b03John McCall
22644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // C++ 11p3: Members of a class defined with the keyword class are private
22654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // by default. Members of a class defined with the keywords struct or union
22664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // are public by default.
22674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  AccessSpecifier CurAS;
22684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (TagType == DeclSpec::TST_class)
22694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_private;
22704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  else
22714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_public;
22725f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  ParsedAttributes AccessAttrs(AttrFactory);
22734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
227407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  if (TagDecl) {
227507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    // While we still have something to read, read the member-declarations.
227607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
227707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Each iteration of this loop reads one member-declaration.
227807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor
22794e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
2280563a645de82231a55e221fe655b7188bf8369662Francois Pichet          Tok.is(tok::kw___if_not_exists))) {
2281563a645de82231a55e221fe655b7188bf8369662Francois Pichet        ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
2282563a645de82231a55e221fe655b7188bf8369662Francois Pichet        continue;
2283563a645de82231a55e221fe655b7188bf8369662Francois Pichet      }
2284563a645de82231a55e221fe655b7188bf8369662Francois Pichet
228507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Check for extraneous top-level semicolon.
228607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      if (Tok.is(tok::semi)) {
228707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        Diag(Tok, diag::ext_extra_struct_semi)
228807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor          << DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
228907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor          << FixItHint::CreateRemoval(Tok.getLocation());
229007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        ConsumeToken();
229107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        continue;
229207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      }
22931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2294aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman      if (Tok.is(tok::annot_pragma_vis)) {
2295aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman        HandlePragmaVisibility();
2296aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman        continue;
2297aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman      }
2298aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman
2299aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman      if (Tok.is(tok::annot_pragma_pack)) {
2300aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman        HandlePragmaPack();
2301aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman        continue;
2302aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman      }
2303aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman
230407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      AccessSpecifier AS = getAccessSpecifierIfPresent();
230507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      if (AS != AS_none) {
230607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        // Current token is a C++ access specifier.
230707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        CurAS = AS;
230807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        SourceLocation ASLoc = Tok.getLocation();
230913f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        unsigned TokLength = Tok.getLength();
231007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        ConsumeToken();
23115f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen        AccessAttrs.clear();
23125f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen        MaybeParseGNUAttributes(AccessAttrs);
23135f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
231413f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        SourceLocation EndLoc;
231513f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        if (Tok.is(tok::colon)) {
231613f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          EndLoc = Tok.getLocation();
231713f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          ConsumeToken();
231813f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        } else if (Tok.is(tok::semi)) {
231913f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          EndLoc = Tok.getLocation();
232013f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          ConsumeToken();
232113f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          Diag(EndLoc, diag::err_expected_colon)
232213f8daf70637f8f295134ac8e089dd7721e09085David Blaikie            << FixItHint::CreateReplacement(EndLoc, ":");
232313f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        } else {
232413f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          EndLoc = ASLoc.getLocWithOffset(TokLength);
232513f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          Diag(EndLoc, diag::err_expected_colon)
232613f8daf70637f8f295134ac8e089dd7721e09085David Blaikie            << FixItHint::CreateInsertion(EndLoc, ":");
232713f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        }
2328c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen
2329c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen        if (Actions.ActOnAccessSpecifier(AS, ASLoc, EndLoc,
2330c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen                                         AccessAttrs.getList())) {
2331c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen          // found another attribute than only annotations
2332c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen          AccessAttrs.clear();
2333c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen        }
2334c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen
233507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        continue;
233607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      }
23374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
233807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // FIXME: Make sure we don't have a template here.
23394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
234007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Parse all the comma separated declarators.
23415f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      ParseCXXClassMemberDeclaration(CurAS, AccessAttrs.getList());
234207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    }
23431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23444a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
234507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  } else {
234607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    SkipUntil(tok::r_brace, false, false);
23474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
23481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // If attributes exist after class contents, parse them.
23500b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
23517f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseGNUAttributes(attrs);
23524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
235342a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
235423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
23554a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                              T.getOpenLocation(),
23564a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                              T.getCloseLocation(),
23577f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                              attrs.getList());
23584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
235974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  // C++11 [class.mem]p2:
236074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  //   Within the class member-specification, the class is regarded as complete
236174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  //   within function bodies, default arguments, exception-specifications, and
236274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  //   brace-or-equal-initializers for non-static data members (including such
236374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  //   things in nested classes).
236407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  if (TagDecl && NonNestedClass) {
23654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // We are not inside a nested class. This class and its nested classes
236672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    // are complete and we can parse the delayed portions of method
2367eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    // declarations and the lexed inline method definitions, along with any
2368eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    // delayed attributes.
2369e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor    SourceLocation SavedPrevTokLocation = PrevTokLocation;
2370eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    ParseLexedAttributes(getCurrentClass());
23716569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDeclarations(getCurrentClass());
2372a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith
2373a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith    // We've finished with all pending member declarations.
2374a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith    Actions.ActOnFinishCXXMemberDecls();
2375a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith
23767a614d8380297fcd2bc23986241905d97222948cRichard Smith    ParseLexedMemberInitializers(getCurrentClass());
23776569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDefs(getCurrentClass());
2378e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor    PrevTokLocation = SavedPrevTokLocation;
23794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
23804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
238142a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
23824a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,
23834a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                     T.getCloseLocation());
2384db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall
23854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Leave the class scope.
23866569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingDef.Pop();
23878935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ClassScope.Exit();
23884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
23897ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
23907ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer,
23917ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a
23927ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers
23937ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below:
23947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
23957ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code
23967ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { };
23977ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base {
23987ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   int x;
23997ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   float f;
24007ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public:
24017ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   Derived(float f) : Base(), x(17), f(f) { }
24027ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// };
24037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode
24047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
24051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  ctor-initializer:
24061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///          ':' mem-initializer-list
24077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
24081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  mem-initializer-list:
24093fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor///          mem-initializer ...[opt]
24103fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor///          mem-initializer ...[opt] , mem-initializer-list
2411d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
24127ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
24137ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
241428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  // Poison the SEH identifiers so they are flagged as illegal in constructor initializers
241528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true);
24167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation ColonLoc = ConsumeToken();
24171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24185f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<CXXCtorInitializer*, 4> MemInitializers;
24199db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  bool AnyErrors = false;
2420193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
24217ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  do {
24220133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    if (Tok.is(tok::code_completion)) {
24230133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      Actions.CodeCompleteConstructorInitializer(ConstructorDecl,
24240133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor                                                 MemInitializers.data(),
24250133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor                                                 MemInitializers.size());
24267d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return cutOffParsing();
24270133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    } else {
24280133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
24290133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      if (!MemInit.isInvalid())
24300133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor        MemInitializers.push_back(MemInit.get());
24310133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      else
24320133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor        AnyErrors = true;
24330133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    }
24340133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor
24357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    if (Tok.is(tok::comma))
24367ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      ConsumeToken();
24377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    else if (Tok.is(tok::l_brace))
24387ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
2439b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor    // If the next token looks like a base or member initializer, assume that
2440b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor    // we're just missing a comma.
2441751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor    else if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) {
2442751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor      SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
2443751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor      Diag(Loc, diag::err_ctor_init_missing_comma)
2444751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor        << FixItHint::CreateInsertion(Loc, ", ");
2445751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor    } else {
24467ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      // Skip over garbage, until we get to '{'.  Don't eat the '{'.
2447d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl      Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
24487ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      SkipUntil(tok::l_brace, true, true);
24497ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
24507ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    }
24517ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  } while (true);
24527ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
24531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc,
24549db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                               MemInitializers.data(), MemInitializers.size(),
24559db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                               AnyErrors);
24567ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
24577ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
24587ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is
24597ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one
24607ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See
24617ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example.
24627ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
24637ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer:
24647ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         mem-initializer-id '(' expression-list[opt] ')'
2465dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// [C++0x] mem-initializer-id braced-init-list
24661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
24677ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id:
24687ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         '::'[opt] nested-name-specifier[opt] class-name
24697ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         identifier
2470d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
2471bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  // parse '::'[opt] nested-name-specifier[opt]
2472bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  CXXScopeSpec SS;
2473efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
2474b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TemplateTypeTy;
2475961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (Tok.is(tok::annot_template_id)) {
247625a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
2477d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor    if (TemplateId->Kind == TNK_Type_template ||
2478d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor        TemplateId->Kind == TNK_Dependent_template_name) {
2479059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
2480961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
2481b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      TemplateTypeTy = getTypeAnnotation(Tok);
2482961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    }
2483961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  }
2484f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  // Uses of decltype will already have been converted to annot_decltype by
2485f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  // ParseOptionalCXXScopeSpecifier at this point.
2486f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  if (!TemplateTypeTy && Tok.isNot(tok::identifier)
2487f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie      && Tok.isNot(tok::annot_decltype)) {
24881ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_member_or_base_name);
24897ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
24907ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
24911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2492f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  IdentifierInfo *II = 0;
2493f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  DeclSpec DS(AttrFactory);
2494f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  SourceLocation IdLoc = Tok.getLocation();
2495f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  if (Tok.is(tok::annot_decltype)) {
2496f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie    // Get the decltype expression, if there is one.
2497f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie    ParseDecltypeSpecifier(DS);
2498f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  } else {
2499f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie    if (Tok.is(tok::identifier))
2500f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie      // Get the identifier. This may be a member name or a class name,
2501f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie      // but we'll let the semantic analysis determine which it is.
2502f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie      II = Tok.getIdentifierInfo();
2503f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie    ConsumeToken();
2504f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  }
2505f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie
25067ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
25077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Parse the '('.
25084e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
25097fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith    Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
25107fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith
25116df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    ExprResult InitList = ParseBraceInitializer();
25126df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    if (InitList.isInvalid())
25136df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      return true;
25146df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
25156df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    SourceLocation EllipsisLoc;
25166df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    if (Tok.is(tok::ellipsis))
25176df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      EllipsisLoc = ConsumeToken();
25186df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
25196df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
2520f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie                                       TemplateTypeTy, DS, IdLoc,
2521f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie                                       InitList.take(), EllipsisLoc);
2522dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl  } else if(Tok.is(tok::l_paren)) {
25234a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    BalancedDelimiterTracker T(*this, tok::l_paren);
25244a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeOpen();
2525dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl
2526dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    // Parse the optional expression-list.
2527dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    ExprVector ArgExprs(Actions);
2528dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    CommaLocsTy CommaLocs;
2529dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
2530dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl      SkipUntil(tok::r_paren);
2531dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl      return true;
2532dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    }
25337ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
25344a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
25357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
2536dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    SourceLocation EllipsisLoc;
2537dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    if (Tok.is(tok::ellipsis))
2538dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl      EllipsisLoc = ConsumeToken();
25397ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
2540dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
2541f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie                                       TemplateTypeTy, DS, IdLoc,
25424a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                       T.getOpenLocation(), ArgExprs.take(),
25434a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                       ArgExprs.size(), T.getCloseLocation(),
2544dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl                                       EllipsisLoc);
2545dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl  }
2546dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl
25474e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  Diag(Tok, getLangOpts().CPlusPlus0x ? diag::err_expected_lparen_or_lbrace
2548dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl                                  : diag::err_expected_lparen);
2549dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl  return true;
25507ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
25510fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
25527acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// \brief Parse a C++ exception-specification if present (C++0x [except.spec]).
25530fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
2554a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       exception-specification:
25557acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         dynamic-exception-specification
25567acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         noexcept-specification
25577acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///
25587acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///       noexcept-specification:
25597acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         'noexcept'
25607acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         'noexcept' '(' constant-expression ')'
25617acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType
256274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas GregorParser::tryParseExceptionSpecification(bool Delayed,
256374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                    SourceRange &SpecificationRange,
25645f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                    SmallVectorImpl<ParsedType> &DynamicExceptions,
25655f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                    SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
256674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                    ExprResult &NoexceptExpr,
256774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                    CachedTokens *&ExceptionSpecTokens) {
25687acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  ExceptionSpecificationType Result = EST_None;
256974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  ExceptionSpecTokens = 0;
257074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
257174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  // Handle delayed parsing of exception-specifications.
257274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  if (Delayed) {
257374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    if (Tok.isNot(tok::kw_throw) && Tok.isNot(tok::kw_noexcept))
257474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      return EST_None;
257574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
257674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Consume and cache the starting token.
257774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    bool IsNoexcept = Tok.is(tok::kw_noexcept);
257874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    Token StartTok = Tok;
257974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    SpecificationRange = SourceRange(ConsumeToken());
258074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
258174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Check for a '('.
258274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    if (!Tok.is(tok::l_paren)) {
258374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      // If this is a bare 'noexcept', we're done.
258474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      if (IsNoexcept) {
258574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor        Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
258674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor        NoexceptExpr = 0;
258774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor        return EST_BasicNoexcept;
258874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      }
258974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
259074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      Diag(Tok, diag::err_expected_lparen_after) << "throw";
259174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      return EST_DynamicNone;
259274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    }
259374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
259474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Cache the tokens for the exception-specification.
259574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    ExceptionSpecTokens = new CachedTokens;
259674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    ExceptionSpecTokens->push_back(StartTok); // 'throw' or 'noexcept'
259774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    ExceptionSpecTokens->push_back(Tok); // '('
259874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    SpecificationRange.setEnd(ConsumeParen()); // '('
259974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
260074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    if (!ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens,
260174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                              /*StopAtSemi=*/true,
260274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                              /*ConsumeFinalToken=*/true)) {
260374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      NoexceptExpr = 0;
260474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      delete ExceptionSpecTokens;
260574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      ExceptionSpecTokens = 0;
260674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      return IsNoexcept? EST_BasicNoexcept : EST_DynamicNone;
260774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    }
260874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    SpecificationRange.setEnd(Tok.getLocation());
260974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
261074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Add the 'stop' token.
261174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    Token End;
261274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    End.startToken();
261374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    End.setKind(tok::cxx_exceptspec_end);
261474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    End.setLocation(Tok.getLocation());
261574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    ExceptionSpecTokens->push_back(End);
261674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    return EST_Delayed;
261774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  }
261874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
26197acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // See if there's a dynamic specification.
26207acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.is(tok::kw_throw)) {
26217acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Result = ParseDynamicExceptionSpecification(SpecificationRange,
26227acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                                DynamicExceptions,
26237acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                                DynamicExceptionRanges);
26247acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    assert(DynamicExceptions.size() == DynamicExceptionRanges.size() &&
26257acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl           "Produced different number of exception types and ranges.");
26267acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
26277acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
26287acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // If there's no noexcept specification, we're done.
26297acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.isNot(tok::kw_noexcept))
26307acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    return Result;
26317acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
2632841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith  Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
2633841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith
26347acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // If we already had a dynamic specification, parse the noexcept for,
26357acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // recovery, but emit a diagnostic and don't store the results.
26367acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SourceRange NoexceptRange;
26377acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  ExceptionSpecificationType NoexceptType = EST_None;
26387acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
26397acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SourceLocation KeywordLoc = ConsumeToken();
26407acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.is(tok::l_paren)) {
26417acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // There is an argument.
26424a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    BalancedDelimiterTracker T(*this, tok::l_paren);
26434a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeOpen();
26447acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptType = EST_ComputedNoexcept;
26457acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptExpr = ParseConstantExpression();
264660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    // The argument must be contextually convertible to bool. We use
264760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    // ActOnBooleanCondition for this purpose.
264860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    if (!NoexceptExpr.isInvalid())
264960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl      NoexceptExpr = Actions.ActOnBooleanCondition(getCurScope(), KeywordLoc,
265060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl                                                   NoexceptExpr.get());
26514a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
26524a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());
26537acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  } else {
26547acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // There is no argument.
26557acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptType = EST_BasicNoexcept;
26567acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptRange = SourceRange(KeywordLoc, KeywordLoc);
26577acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
26587acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
26597acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Result == EST_None) {
26607acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SpecificationRange = NoexceptRange;
26617acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Result = NoexceptType;
26627acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
26637acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // If there's a dynamic specification after a noexcept specification,
26647acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // parse that and ignore the results.
26657acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    if (Tok.is(tok::kw_throw)) {
26667acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
26677acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions,
26687acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                         DynamicExceptionRanges);
26697acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    }
26707acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  } else {
26717acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
26727acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
26737acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
26747acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  return Result;
26757acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl}
26767acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
26777acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// ParseDynamicExceptionSpecification - Parse a C++
26787acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification (C++ [except.spec]).
26797acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///
26807acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///       dynamic-exception-specification:
2681a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         'throw' '(' type-id-list [opt] ')'
2682a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS]    'throw' '(' '...' ')'
26831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
2684a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       type-id-list:
2685a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor///         type-id ... [opt]
2686a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor///         type-id-list ',' type-id ... [opt]
26870fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
26887acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(
26897acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                  SourceRange &SpecificationRange,
26905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                  SmallVectorImpl<ParsedType> &Exceptions,
26915f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                  SmallVectorImpl<SourceRange> &Ranges) {
26920fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  assert(Tok.is(tok::kw_throw) && "expected throw");
26931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
26947acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SpecificationRange.setBegin(ConsumeToken());
26954a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
26964a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.consumeOpen()) {
26977acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Diag(Tok, diag::err_expected_lparen_after) << "throw";
26987acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SpecificationRange.setEnd(SpecificationRange.getBegin());
269960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    return EST_DynamicNone;
27000fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
27010fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
2702a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // Parse throw(...), a Microsoft extension that means "this function
2703a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // can throw anything".
2704a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  if (Tok.is(tok::ellipsis)) {
2705a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    SourceLocation EllipsisLoc = ConsumeToken();
27064e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (!getLangOpts().MicrosoftExt)
2707a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor      Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
27084a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
27094a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    SpecificationRange.setEnd(T.getCloseLocation());
271060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    return EST_MSAny;
2711a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  }
2712a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor
27130fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  // Parse the sequence of type-ids.
2714ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl  SourceRange Range;
27150fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  while (Tok.isNot(tok::r_paren)) {
2716ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    TypeResult Res(ParseTypeName(&Range));
27177acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
2718a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor    if (Tok.is(tok::ellipsis)) {
2719a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      // C++0x [temp.variadic]p5:
2720a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      //   - In a dynamic-exception-specification (15.4); the pattern is a
2721a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      //     type-id.
2722a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      SourceLocation Ellipsis = ConsumeToken();
27237acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      Range.setEnd(Ellipsis);
2724a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      if (!Res.isInvalid())
2725a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor        Res = Actions.ActOnPackExpansion(Res.get(), Ellipsis);
2726a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor    }
27277acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
2728ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    if (!Res.isInvalid()) {
27297dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl      Exceptions.push_back(Res.get());
2730ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl      Ranges.push_back(Range);
2731ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    }
2732a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor
27330fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor    if (Tok.is(tok::comma))
27340fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      ConsumeToken();
27357dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl    else
27360fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      break;
27370fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
27380fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
27394a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
27404a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  SpecificationRange.setEnd(T.getCloseLocation());
274160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl  return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic;
27420fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor}
27436569d68745c8213709740337d2be52b031384f58Douglas Gregor
2744dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// ParseTrailingReturnType - Parse a trailing return type on a new-style
2745dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// function declaration.
2746ae7902c4293d9de8b9591759513f0d075f45022aDouglas GregorTypeResult Parser::ParseTrailingReturnType(SourceRange &Range) {
2747dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  assert(Tok.is(tok::arrow) && "expected arrow");
2748dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
2749dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  ConsumeToken();
2750dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
27517796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  return ParseTypeName(&Range, Declarator::TrailingReturnContext);
2752dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor}
2753dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
27546569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief We have just started parsing the definition of a new class,
27556569d68745c8213709740337d2be52b031384f58Douglas Gregor/// so push that class onto our stack of classes that is currently
27566569d68745c8213709740337d2be52b031384f58Douglas Gregor/// being parsed.
2757eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallSema::ParsingClassState
2758eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallParser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass) {
275926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  assert((NonNestedClass || !ClassStack.empty()) &&
27606569d68745c8213709740337d2be52b031384f58Douglas Gregor         "Nested class without outer class");
276126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass));
2762eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  return Actions.PushParsingClass();
27636569d68745c8213709740337d2be52b031384f58Douglas Gregor}
27646569d68745c8213709740337d2be52b031384f58Douglas Gregor
27656569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Deallocate the given parsed class and all of its nested
27666569d68745c8213709740337d2be52b031384f58Douglas Gregor/// classes.
27676569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
2768d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I)
2769d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    delete Class->LateParsedDeclarations[I];
27706569d68745c8213709740337d2be52b031384f58Douglas Gregor  delete Class;
27716569d68745c8213709740337d2be52b031384f58Douglas Gregor}
27726569d68745c8213709740337d2be52b031384f58Douglas Gregor
27736569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Pop the top class of the stack of classes that are
27746569d68745c8213709740337d2be52b031384f58Douglas Gregor/// currently being parsed.
27756569d68745c8213709740337d2be52b031384f58Douglas Gregor///
27766569d68745c8213709740337d2be52b031384f58Douglas Gregor/// This routine should be called when we have finished parsing the
27776569d68745c8213709740337d2be52b031384f58Douglas Gregor/// definition of a class, but have not yet popped the Scope
27786569d68745c8213709740337d2be52b031384f58Douglas Gregor/// associated with the class's definition.
27796569d68745c8213709740337d2be52b031384f58Douglas Gregor///
27806569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \returns true if the class we've popped is a top-level class,
27816569d68745c8213709740337d2be52b031384f58Douglas Gregor/// false otherwise.
2782eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Parser::PopParsingClass(Sema::ParsingClassState state) {
27836569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");
27841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2785eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  Actions.PopParsingClass(state);
2786eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
27876569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingClass *Victim = ClassStack.top();
27886569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.pop();
27896569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (Victim->TopLevelClass) {
27906569d68745c8213709740337d2be52b031384f58Douglas Gregor    // Deallocate all of the nested classes of this class,
27916569d68745c8213709740337d2be52b031384f58Douglas Gregor    // recursively: we don't need to keep any of this information.
27926569d68745c8213709740337d2be52b031384f58Douglas Gregor    DeallocateParsedClasses(Victim);
27936569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
27941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
27956569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Missing top-level class?");
27966569d68745c8213709740337d2be52b031384f58Douglas Gregor
2797d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (Victim->LateParsedDeclarations.empty()) {
27986569d68745c8213709740337d2be52b031384f58Douglas Gregor    // The victim is a nested class, but we will not need to perform
27996569d68745c8213709740337d2be52b031384f58Douglas Gregor    // any processing after the definition of this class since it has
28006569d68745c8213709740337d2be52b031384f58Douglas Gregor    // no members whose handling was delayed. Therefore, we can just
28016569d68745c8213709740337d2be52b031384f58Douglas Gregor    // remove this nested class.
2802d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    DeallocateParsedClasses(Victim);
28036569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
28046569d68745c8213709740337d2be52b031384f58Douglas Gregor  }
28056569d68745c8213709740337d2be52b031384f58Douglas Gregor
28066569d68745c8213709740337d2be52b031384f58Douglas Gregor  // This nested class has some members that will need to be processed
28076569d68745c8213709740337d2be52b031384f58Douglas Gregor  // after the top-level class is completely defined. Therefore, add
28086569d68745c8213709740337d2be52b031384f58Douglas Gregor  // it to the list of nested classes within its parent.
280923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  assert(getCurScope()->isClassScope() && "Nested class outside of class scope?");
2810d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ClassStack.top()->LateParsedDeclarations.push_back(new LateParsedClass(this, Victim));
281123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope();
28126569d68745c8213709740337d2be52b031384f58Douglas Gregor}
2813bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2814c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// \brief Try to parse an 'identifier' which appears within an attribute-token.
2815c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///
2816c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// \return the parsed identifier on success, and 0 if the next token is not an
2817c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute-token.
2818c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///
2819c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// C++11 [dcl.attr.grammar]p3:
2820c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///   If a keyword or an alternative token that satisfies the syntactic
2821c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///   requirements of an identifier is contained in an attribute-token,
2822c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///   it is considered an identifier.
2823c56298d87a9df507805a548d7d515e8b511df2c0Richard SmithIdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(SourceLocation &Loc) {
2824c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  switch (Tok.getKind()) {
2825c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  default:
2826c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    // Identifiers and keywords have identifier info attached.
2827c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
2828c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      Loc = ConsumeToken();
2829c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      return II;
2830c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    }
2831c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    return 0;
2832c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith
2833c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::ampamp:       // 'and'
2834c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::pipe:         // 'bitor'
2835c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::pipepipe:     // 'or'
2836c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::caret:        // 'xor'
2837c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::tilde:        // 'compl'
2838c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::amp:          // 'bitand'
2839c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::ampequal:     // 'and_eq'
2840c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::pipeequal:    // 'or_eq'
2841c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::caretequal:   // 'xor_eq'
2842c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::exclaim:      // 'not'
2843c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::exclaimequal: // 'not_eq'
2844c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    // Alternative tokens do not have identifier info, but their spelling
2845c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    // starts with an alphabetical character.
2846c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    llvm::SmallString<8> SpellingBuf;
2847c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    StringRef Spelling = PP.getSpelling(Tok.getLocation(), SpellingBuf);
2848c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    if (std::isalpha(Spelling[0])) {
2849c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      Loc = ConsumeToken();
28500eb7526cd2524af78fb9a2a2522045fb25fc3d27Benjamin Kramer      return &PP.getIdentifierTable().get(Spelling);
2851c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    }
2852c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    return 0;
2853c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  }
2854c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith}
2855c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith
2856c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier. Currently
28573497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// only parses standard attributes.
2858bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
28596ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-specifier:
2860bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' '[' attribute-list ']' ']'
286182d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne///         alignment-specifier
2862bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
28636ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-list:
2864bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute[opt]
2865bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-list ',' attribute[opt]
2866c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///         attribute '...'
2867c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///         attribute-list ',' attribute '...'
2868bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
28696ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute:
2870bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-token attribute-argument-clause[opt]
2871bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
28726ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-token:
2873bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
2874bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-scoped-token
2875bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
28766ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-scoped-token:
2877bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-namespace '::' identifier
2878bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
28796ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-namespace:
2880bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
2881bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
28826ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-argument-clause:
2883bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
2884bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
28856ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] balanced-token-seq:
2886bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token
2887bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token-seq balanced-token
2888bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
28896ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] balanced-token:
2890bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
2891bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' balanced-token-seq ']'
2892bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '{' balanced-token-seq '}'
2893bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         any token but '(', ')', '[', ']', '{', or '}'
2894c56298d87a9df507805a548d7d515e8b511df2c0Richard Smithvoid Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
28953497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne                                          SourceLocation *endLoc) {
289682d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne  if (Tok.is(tok::kw_alignas)) {
289741be673e93ed225b45479557b20ff19b3082bae8Richard Smith    Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas);
289882d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne    ParseAlignmentSpecifier(attrs, endLoc);
289982d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne    return;
290082d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne  }
290182d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne
2902bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
29036ee326af4e77e6f05973486097884d7431f2108dRichard Smith      && "Not a C++11 attribute list");
2904bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
290541be673e93ed225b45479557b20ff19b3082bae8Richard Smith  Diag(Tok.getLocation(), diag::warn_cxx98_compat_attribute);
290641be673e93ed225b45479557b20ff19b3082bae8Richard Smith
2907bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
2908bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
2909193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
2910c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  while (Tok.isNot(tok::r_square)) {
2911bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // attribute not present
2912bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::comma)) {
2913bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
2914bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      continue;
2915bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2916bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2917c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    SourceLocation ScopeLoc, AttrLoc;
2918c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    IdentifierInfo *ScopeName = 0, *AttrName = 0;
2919c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith
2920c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    AttrName = TryParseCXX11AttributeIdentifier(AttrLoc);
2921c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    if (!AttrName)
2922c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      // Break out to the "expected ']'" diagnostic.
2923c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      break;
2924193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
2925bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // scoped attribute
2926bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::coloncolon)) {
2927bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
2928bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2929c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      ScopeName = AttrName;
2930c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      ScopeLoc = AttrLoc;
2931c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith
2932c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      AttrName = TryParseCXX11AttributeIdentifier(AttrLoc);
2933c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      if (!AttrName) {
2934bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        Diag(Tok.getLocation(), diag::err_expected_ident);
2935bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        SkipUntil(tok::r_square, tok::comma, true, true);
2936bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        continue;
2937bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2938bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2939bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2940bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    bool AttrParsed = false;
2941bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // No scoped names are supported; ideally we could put all non-standard
2942bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // attributes into namespaces.
2943bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (!ScopeName) {
29446ee326af4e77e6f05973486097884d7431f2108dRichard Smith      switch (AttributeList::getKind(AttrName)) {
2945bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // No arguments
29467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_carries_dependency:
294715e14a289583616e582a23b320933e846a742626Anders Carlsson      case AttributeList::AT_noreturn: {
2948bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        if (Tok.is(tok::l_paren)) {
2949c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith          Diag(Tok.getLocation(), diag::err_cxx11_attribute_forbids_arguments)
2950bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt            << AttrName->getName();
2951bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          break;
2952bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        }
2953bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
29540b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall        attrs.addNew(AttrName, AttrLoc, 0, AttrLoc, 0,
29550b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                     SourceLocation(), 0, 0, false, true);
2956bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        AttrParsed = true;
2957bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        break;
2958bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2959bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2960bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // Silence warnings
2961bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      default: break;
2962bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2963bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2964bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2965bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // Skip the entire parameter clause, if any
2966bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (!AttrParsed && Tok.is(tok::l_paren)) {
2967bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeParen();
2968bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // SkipUntil maintains the balancedness of tokens.
2969bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      SkipUntil(tok::r_paren, false);
2970bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
29716ee326af4e77e6f05973486097884d7431f2108dRichard Smith
2972c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    if (Tok.is(tok::ellipsis)) {
2973c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      if (AttrParsed)
2974c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith        Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis)
2975c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith          << AttrName->getName();
29766ee326af4e77e6f05973486097884d7431f2108dRichard Smith      ConsumeToken();
2977c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    }
2978bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
2979bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2980bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
2981bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
29823497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne  if (endLoc)
29833497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne    *endLoc = Tok.getLocation();
2984bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
2985bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
29863497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne}
29873497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne
2988c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// ParseCXX11Attributes - Parse a C++0x attribute-specifier-seq.
29893497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne///
29903497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// attribute-specifier-seq:
29913497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne///       attribute-specifier-seq[opt] attribute-specifier
2992c56298d87a9df507805a548d7d515e8b511df2c0Richard Smithvoid Parser::ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
29933497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne                                  SourceLocation *endLoc) {
29943497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne  SourceLocation StartLoc = Tok.getLocation(), Loc;
29953497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne  if (!endLoc)
29963497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne    endLoc = &Loc;
29973497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne
29988828ee7faa42f889ade3bb635dc5f1338be671b1Douglas Gregor  do {
2999c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    ParseCXX11AttributeSpecifier(attrs, endLoc);
30006ee326af4e77e6f05973486097884d7431f2108dRichard Smith  } while (isCXX11AttributeSpecifier());
3001bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
30023497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne  attrs.Range = SourceRange(StartLoc, *endLoc);
3003bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
3004bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
3005334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ParseMicrosoftAttributes - Parse a Microsoft attribute [Attr]
3006334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///
3007334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute:
3008334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             '[' token-seq ']'
3009334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///
3010334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute-seq:
3011334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             ms-attribute[opt]
3012334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             ms-attribute ms-attribute-seq
30137f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCallvoid Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs,
30147f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                      SourceLocation *endLoc) {
3015334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
3016334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet
3017334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  while (Tok.is(tok::l_square)) {
30186ee326af4e77e6f05973486097884d7431f2108dRichard Smith    // FIXME: If this is actually a C++11 attribute, parse it as one.
3019334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    ConsumeBracket();
3020334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    SkipUntil(tok::r_square, true, true);
30217f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    if (endLoc) *endLoc = Tok.getLocation();
3022334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
3023334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  }
3024334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet}
3025563a645de82231a55e221fe655b7188bf8369662Francois Pichet
3026563a645de82231a55e221fe655b7188bf8369662Francois Pichetvoid Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
3027563a645de82231a55e221fe655b7188bf8369662Francois Pichet                                                    AccessSpecifier& CurAS) {
30283896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  IfExistsCondition Result;
3029563a645de82231a55e221fe655b7188bf8369662Francois Pichet  if (ParseMicrosoftIfExistsCondition(Result))
3030563a645de82231a55e221fe655b7188bf8369662Francois Pichet    return;
3031563a645de82231a55e221fe655b7188bf8369662Francois Pichet
30323896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  BalancedDelimiterTracker Braces(*this, tok::l_brace);
30333896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  if (Braces.consumeOpen()) {
3034563a645de82231a55e221fe655b7188bf8369662Francois Pichet    Diag(Tok, diag::err_expected_lbrace);
3035563a645de82231a55e221fe655b7188bf8369662Francois Pichet    return;
3036563a645de82231a55e221fe655b7188bf8369662Francois Pichet  }
3037563a645de82231a55e221fe655b7188bf8369662Francois Pichet
30383896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  switch (Result.Behavior) {
30393896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Parse:
30403896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    // Parse the declarations below.
30413896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    break;
30423896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
30433896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Dependent:
30443896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
30453896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor      << Result.IsIfExists;
30463896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    // Fall through to skip.
30473896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
30483896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Skip:
30493896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    Braces.skipToEnd();
3050563a645de82231a55e221fe655b7188bf8369662Francois Pichet    return;
3051563a645de82231a55e221fe655b7188bf8369662Francois Pichet  }
3052563a645de82231a55e221fe655b7188bf8369662Francois Pichet
30533896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
3054563a645de82231a55e221fe655b7188bf8369662Francois Pichet    // __if_exists, __if_not_exists can nest.
3055563a645de82231a55e221fe655b7188bf8369662Francois Pichet    if ((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists))) {
3056563a645de82231a55e221fe655b7188bf8369662Francois Pichet      ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
3057563a645de82231a55e221fe655b7188bf8369662Francois Pichet      continue;
3058563a645de82231a55e221fe655b7188bf8369662Francois Pichet    }
3059563a645de82231a55e221fe655b7188bf8369662Francois Pichet
3060563a645de82231a55e221fe655b7188bf8369662Francois Pichet    // Check for extraneous top-level semicolon.
3061563a645de82231a55e221fe655b7188bf8369662Francois Pichet    if (Tok.is(tok::semi)) {
3062563a645de82231a55e221fe655b7188bf8369662Francois Pichet      Diag(Tok, diag::ext_extra_struct_semi)
3063563a645de82231a55e221fe655b7188bf8369662Francois Pichet        << DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
3064563a645de82231a55e221fe655b7188bf8369662Francois Pichet        << FixItHint::CreateRemoval(Tok.getLocation());
3065563a645de82231a55e221fe655b7188bf8369662Francois Pichet      ConsumeToken();
3066563a645de82231a55e221fe655b7188bf8369662Francois Pichet      continue;
3067563a645de82231a55e221fe655b7188bf8369662Francois Pichet    }
3068563a645de82231a55e221fe655b7188bf8369662Francois Pichet
3069563a645de82231a55e221fe655b7188bf8369662Francois Pichet    AccessSpecifier AS = getAccessSpecifierIfPresent();
3070563a645de82231a55e221fe655b7188bf8369662Francois Pichet    if (AS != AS_none) {
3071563a645de82231a55e221fe655b7188bf8369662Francois Pichet      // Current token is a C++ access specifier.
3072563a645de82231a55e221fe655b7188bf8369662Francois Pichet      CurAS = AS;
3073563a645de82231a55e221fe655b7188bf8369662Francois Pichet      SourceLocation ASLoc = Tok.getLocation();
3074563a645de82231a55e221fe655b7188bf8369662Francois Pichet      ConsumeToken();
3075563a645de82231a55e221fe655b7188bf8369662Francois Pichet      if (Tok.is(tok::colon))
3076563a645de82231a55e221fe655b7188bf8369662Francois Pichet        Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
3077563a645de82231a55e221fe655b7188bf8369662Francois Pichet      else
3078563a645de82231a55e221fe655b7188bf8369662Francois Pichet        Diag(Tok, diag::err_expected_colon);
3079563a645de82231a55e221fe655b7188bf8369662Francois Pichet      ConsumeToken();
3080563a645de82231a55e221fe655b7188bf8369662Francois Pichet      continue;
3081563a645de82231a55e221fe655b7188bf8369662Francois Pichet    }
3082563a645de82231a55e221fe655b7188bf8369662Francois Pichet
3083563a645de82231a55e221fe655b7188bf8369662Francois Pichet    // Parse all the comma separated declarators.
30845f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    ParseCXXClassMemberDeclaration(CurAS, 0);
3085563a645de82231a55e221fe655b7188bf8369662Francois Pichet  }
30863896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
30873896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  Braces.consumeClose();
3088563a645de82231a55e221fe655b7188bf8369662Francois Pichet}
3089