ParseDeclCXX.cpp revision c640058aa7f224a71ce3b1d2601d84e1b57f82d3
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
141b7f89846f10681ce3cbe89ef5d60691d55bd918Douglas Gregor#include "clang/Parse/Parser.h"
1555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "RAIIObjectsForParser.h"
163f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose#include "clang/Basic/CharInfo.h"
1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/OperatorKinds.h"
18500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h"
1919510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
2019510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/ParsedTemplate.h"
21f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall#include "clang/Sema/PrettyDeclStackTrace.h"
2255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Scope.h"
23e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall#include "clang/Sema/SemaDiagnostic.h"
248fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer#include "llvm/ADT/SmallString.h"
258f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattnerusing namespace clang;
268f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner
278f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// ParseNamespace - We know that the current token is a namespace keyword. This
28d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// may either be a top level namespace or a block-level namespace alias. If
29d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// there was an inline keyword, it has already been parsed.
308f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
318f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       namespace-definition: [C++ 7.3: basic.namespace]
328f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         named-namespace-definition
338f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         unnamed-namespace-definition
348f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
358f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       unnamed-namespace-definition:
36d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' attributes[opt] '{' namespace-body '}'
378f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
388f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       named-namespace-definition:
398f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         original-namespace-definition
408f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         extension-namespace-definition
418f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
428f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       original-namespace-definition:
43d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' identifier attributes[opt]
44d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///             '{' namespace-body '}'
458f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
468f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       extension-namespace-definition:
47d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' original-namespace-name
48d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///             '{' namespace-body '}'
491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
508f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       namespace-alias-definition:  [C++ 7.3.2: namespace.alias]
518f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         'namespace' identifier '=' qualified-namespace-specifier ';'
528f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
53d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespace(unsigned Context,
54d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl                             SourceLocation &DeclEnd,
55d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl                             SourceLocation InlineLoc) {
5604d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
578f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation NamespaceLoc = ConsumeToken();  // eat the 'namespace'.
589735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian  ObjCDeclContextSwitch ObjCDC(*this);
59a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian
6049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
6123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteNamespaceDecl(getCurScope());
627d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
637d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
6449f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
65193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
668f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation IdentLoc;
678f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  IdentifierInfo *Ident = 0;
68f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  std::vector<SourceLocation> ExtraIdentLoc;
69f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  std::vector<IdentifierInfo*> ExtraIdent;
70f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  std::vector<SourceLocation> ExtraNamespaceLoc;
716a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
726a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  Token attrTok;
731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7404d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  if (Tok.is(tok::identifier)) {
758f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    Ident = Tok.getIdentifierInfo();
768f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    IdentLoc = ConsumeToken();  // eat the identifier.
77f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    while (Tok.is(tok::coloncolon) && NextToken().is(tok::identifier)) {
78f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ExtraNamespaceLoc.push_back(ConsumeToken());
79f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ExtraIdent.push_back(Tok.getIdentifierInfo());
80f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ExtraIdentLoc.push_back(ConsumeToken());
81f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
828f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  }
831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
848f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  // Read label attributes, if present.
850b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
866a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::kw___attribute)) {
876a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor    attrTok = Tok;
887f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
896a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
916a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::equal)) {
92e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber    if (Ident == 0) {
93e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber      Diag(Tok, diag::err_expected_ident);
94e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber      // Skip to end of the definition and eat the ';'.
95e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber      SkipUntil(tok::semi);
96e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber      return 0;
97e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber    }
987f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    if (!attrs.empty())
996a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor      Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
100d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl    if (InlineLoc.isValid())
101d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl      Diag(InlineLoc, diag::err_inline_namespace_alias)
102d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl          << FixItHint::CreateRemoval(InlineLoc);
1039735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian    return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
1046a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
1051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
106f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
1074a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_brace);
1084a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.consumeOpen()) {
109f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    if (!ExtraIdent.empty()) {
110f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
111f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back());
112f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Diag(Tok, Ident ? diag::err_expected_lbrace :
1145144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner         diag::err_expected_ident_lbrace);
115d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
1165144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  }
1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() ||
11923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      getCurScope()->isInObjcMethodScope() || getCurScope()->getBlockParent() ||
12023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      getCurScope()->getFnParent()) {
121f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    if (!ExtraIdent.empty()) {
122f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
123f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back());
124f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
1254a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope);
12695f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor    SkipUntil(tok::r_brace, false);
127d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
12895f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor  }
12995f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor
130f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  if (!ExtraIdent.empty()) {
131f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    TentativeParsingAction TPA(*this);
132f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    SkipUntil(tok::r_brace, /*StopAtSemi*/false, /*DontConsume*/true);
133f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    Token rBraceToken = Tok;
134f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    TPA.Revert();
135f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
136f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    if (!rBraceToken.is(tok::r_brace)) {
137f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
138f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back());
139f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    } else {
1409910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer      std::string NamespaceFix;
141f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      for (std::vector<IdentifierInfo*>::iterator I = ExtraIdent.begin(),
142f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu           E = ExtraIdent.end(); I != E; ++I) {
143f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu        NamespaceFix += " { namespace ";
144f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu        NamespaceFix += (*I)->getName();
145f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      }
1469910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer
147f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      std::string RBraces;
1489910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer      for (unsigned i = 0, e = ExtraIdent.size(); i != e; ++i)
149f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu        RBraces +=  "} ";
1509910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer
151f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
152f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << FixItHint::CreateReplacement(SourceRange(ExtraNamespaceLoc.front(),
153f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                                      ExtraIdentLoc.back()),
154f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                          NamespaceFix)
155f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << FixItHint::CreateInsertion(rBraceToken.getLocation(), RBraces);
156f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
157f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  }
158f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
15988e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl  // If we're still good, complain about inline namespaces in non-C++0x now.
1607fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith  if (InlineLoc.isValid())
16180ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith    Diag(InlineLoc, getLangOpts().CPlusPlus11 ?
1627fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith         diag::warn_cxx98_compat_inline_namespace : diag::ext_inline_namespace);
16388e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl
1645144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Enter a scope for the namespace.
1655144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  ParseScope NamespaceScope(this, Scope::DeclScope);
1662d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
167d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *NamespcDecl =
168acba90f30876b4140b738f0d3dd0e50724053a96Abramo Bagnara    Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, NamespaceLoc,
1694a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                   IdentLoc, Ident, T.getOpenLocation(),
1704a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                   attrs.getList());
1712d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
172f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc,
173f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing namespace");
1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
175f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  // Parse the contents of the namespace.  This includes parsing recovery on
176f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  // any improperly nested namespaces.
177f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  ParseInnerNamespace(ExtraIdentLoc, ExtraIdent, ExtraNamespaceLoc, 0,
1784a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                      InlineLoc, attrs, T);
1791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1805144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Leave the namespace scope.
1815144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  NamespaceScope.Exit();
1828ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis
1834a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  DeclEnd = T.getCloseLocation();
1844a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  Actions.ActOnFinishNamespaceDef(NamespcDecl, DeclEnd);
1852d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
1865144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  return NamespcDecl;
1878f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner}
188c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
189f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu/// ParseInnerNamespace - Parse the contents of a namespace.
190f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieuvoid Parser::ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc,
191f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 std::vector<IdentifierInfo*>& Ident,
192f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 std::vector<SourceLocation>& NamespaceLoc,
193f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 unsigned int index, SourceLocation& InlineLoc,
194f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 ParsedAttributes& attrs,
1954a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                 BalancedDelimiterTracker &Tracker) {
196f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  if (index == Ident.size()) {
197f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
198f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ParsedAttributesWithRange attrs(AttrFactory);
1994e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith      MaybeParseCXX11Attributes(attrs);
200f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      MaybeParseMicrosoftAttributes(attrs);
201f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ParseExternalDeclaration(attrs);
202f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
2034a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor
2044a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    // The caller is what called check -- we are simply calling
2054a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    // the close for it.
2064a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    Tracker.consumeClose();
207f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
208f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    return;
209f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  }
210f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
211f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  // Parse improperly nested namespaces.
212f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  ParseScope NamespaceScope(this, Scope::DeclScope);
213f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  Decl *NamespcDecl =
214f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    Actions.ActOnStartNamespaceDef(getCurScope(), SourceLocation(),
215f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                   NamespaceLoc[index], IdentLoc[index],
2164a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                   Ident[index], Tracker.getOpenLocation(),
2174a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                   attrs.getList());
218f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
219f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  ParseInnerNamespace(IdentLoc, Ident, NamespaceLoc, ++index, InlineLoc,
2204a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                      attrs, Tracker);
221f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
222f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  NamespaceScope.Exit();
223f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
2244a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  Actions.ActOnFinishNamespaceDef(NamespcDecl, Tracker.getCloseLocation());
225f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu}
226f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
227f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
228f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// alias definition.
229f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson///
230d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
2310b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  SourceLocation AliasLoc,
2320b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  IdentifierInfo *Alias,
2330b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  SourceLocation &DeclEnd) {
234f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  assert(Tok.is(tok::equal) && "Not equal token");
2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
236f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  ConsumeToken(); // eat the '='.
2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23849f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
23923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteNamespaceAliasDecl(getCurScope());
2407d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
2417d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
24249f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
243193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
244f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  CXXScopeSpec SS;
245f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse (optional) nested-name-specifier.
246efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
247f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
248f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
249f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    Diag(Tok, diag::err_expected_namespace_name);
250f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    // Skip to end of the definition and eat the ';'.
251f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    SkipUntil(tok::semi);
252d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
253f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  }
254f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
255f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse identifier.
25603bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  IdentifierInfo *Ident = Tok.getIdentifierInfo();
25703bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  SourceLocation IdentLoc = ConsumeToken();
2581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
259f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Eat the ';'.
26097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
2616869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name,
2626869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner                   "", tok::semi);
2631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
26423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc, Alias,
26503bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson                                        SS, IdentLoc, Ident);
266f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson}
267f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
268c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal
269c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen.
270c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
271c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///       linkage-specification: [C++ 7.5p2: dcl.link]
272c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal '{' declaration-seq[opt] '}'
273c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal declaration
274c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
2757d64271b162eaf5cae264ff64465b28af623dc17Chris LattnerDecl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
276c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor  assert(Tok.is(tok::string_literal) && "Not a string literal!");
277f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<8> LangBuffer;
278453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  bool Invalid = false;
2795f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid);
280453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  if (Invalid)
281d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
282c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
28399831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  // FIXME: This is incorrect: linkage-specifiers are parsed in translation
28499831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  // phase 7, so string-literal concatenation is supposed to occur.
28599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  //   extern "" "C" "" "+" "+" { } is legal.
28699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  if (Tok.hasUDSuffix())
28799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    Diag(Tok, diag::err_invalid_string_udl);
288c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  SourceLocation Loc = ConsumeStringToken();
289c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
290074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  ParseScope LinkageScope(this, Scope::DeclScope);
291d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *LinkageSpec
29223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    = Actions.ActOnStartLinkageSpecification(getCurScope(),
293a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                             DS.getSourceRange().getBegin(),
294d56638180014e60538cd666cd11fde6d4698e051Benjamin Kramer                                             Loc, Lang,
295a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                      Tok.is(tok::l_brace) ? Tok.getLocation()
296074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                           : SourceLocation());
297074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
2980b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributesWithRange attrs(AttrFactory);
2994e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith  MaybeParseCXX11Attributes(attrs);
3007f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseMicrosoftAttributes(attrs);
301193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
302074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (Tok.isNot(tok::l_brace)) {
303f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // Reset the source range in DS, as the leading "extern"
304f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // does not really belong to the inner declaration ...
305f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    DS.SetRangeStart(SourceLocation());
306f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    DS.SetRangeEnd(SourceLocation());
307f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // ... but anyway remember that such an "extern" was seen.
30835f9a196ef897b9559de25aaecd957208f0b4f59Abramo Bagnara    DS.setExternInLinkageSpec(true);
3097f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseExternalDeclaration(attrs, &DS);
31023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
311074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                   SourceLocation());
3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
313f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor
31463a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor  DS.abort();
31563a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor
3167f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  ProhibitAttributes(attrs);
317bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
3184a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_brace);
3194a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
320f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
3210b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    ParsedAttributesWithRange attrs(AttrFactory);
3224e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith    MaybeParseCXX11Attributes(attrs);
3237f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseMicrosoftAttributes(attrs);
3247f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseExternalDeclaration(attrs);
325f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  }
326c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
3274a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
3287d64271b162eaf5cae264ff64465b28af623dc17Chris Lattner  return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
3294a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                                 T.getCloseLocation());
330c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner}
331e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
332f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
333f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'.
334d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
33578b810559d89e996e00684335407443936ce34a1John McCall                                         const ParsedTemplateInfo &TemplateInfo,
33678b810559d89e996e00684335407443936ce34a1John McCall                                               SourceLocation &DeclEnd,
337c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                             ParsedAttributesWithRange &attrs,
338c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                               Decl **OwnedType) {
339f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_using) && "Not using token");
3409735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian  ObjCDeclContextSwitch ObjCDC(*this);
3419735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian
342f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'using'.
343f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation UsingLoc = ConsumeToken();
344f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
34549f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
34623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteUsing(getCurScope());
3477d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
3487d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
34949f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
350193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
35178b810559d89e996e00684335407443936ce34a1John McCall  // 'using namespace' means this is a using-directive.
35278b810559d89e996e00684335407443936ce34a1John McCall  if (Tok.is(tok::kw_namespace)) {
35378b810559d89e996e00684335407443936ce34a1John McCall    // Template parameters are always an error here.
35478b810559d89e996e00684335407443936ce34a1John McCall    if (TemplateInfo.Kind) {
35578b810559d89e996e00684335407443936ce34a1John McCall      SourceRange R = TemplateInfo.getSourceRange();
35678b810559d89e996e00684335407443936ce34a1John McCall      Diag(UsingLoc, diag::err_templated_using_directive)
35778b810559d89e996e00684335407443936ce34a1John McCall        << R << FixItHint::CreateRemoval(R);
35878b810559d89e996e00684335407443936ce34a1John McCall    }
35978b810559d89e996e00684335407443936ce34a1John McCall
3609735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian    return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
36178b810559d89e996e00684335407443936ce34a1John McCall  }
362bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
363162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  // Otherwise, it must be a using-declaration or an alias-declaration.
36478b810559d89e996e00684335407443936ce34a1John McCall
36578b810559d89e996e00684335407443936ce34a1John McCall  // Using declarations can't have attributes.
3667f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  ProhibitAttributes(attrs);
3672f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner
3689735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian  return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd,
369a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian                                    AS_none, OwnedType);
370f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
371f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
372f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes
373f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed.
374f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
375f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       using-directive: [C++ 7.3.p4: namespace.udir]
376f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
377f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name ;
378f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive:
379f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
380f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name attributes[opt] ;
381f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
382d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirective(unsigned Context,
38378b810559d89e996e00684335407443936ce34a1John McCall                                  SourceLocation UsingLoc,
38478b810559d89e996e00684335407443936ce34a1John McCall                                  SourceLocation &DeclEnd,
3857f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                  ParsedAttributes &attrs) {
386f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
387f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
388f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'namespace'.
389f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation NamespcLoc = ConsumeToken();
390f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
39149f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
39223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteUsingDirective(getCurScope());
3937d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
3947d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
39549f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
396193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
397f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  CXXScopeSpec SS;
398f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse (optional) nested-name-specifier.
399efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
400f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
401f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  IdentifierInfo *NamespcName = 0;
402f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation IdentLoc = SourceLocation();
403f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
404f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse namespace-name.
405823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
406f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    Diag(Tok, diag::err_expected_namespace_name);
407f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // If there was invalid namespace name, skip to end of decl, and eat ';'.
408f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    SkipUntil(tok::semi);
409f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
410d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
411f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  }
4121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
413823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse identifier.
414823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  NamespcName = Tok.getIdentifierInfo();
415823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  IdentLoc = ConsumeToken();
4161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
417823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse (optional) attributes (most likely GNU strong-using extension).
418bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  bool GNUAttr = false;
419bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Tok.is(tok::kw___attribute)) {
420bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    GNUAttr = true;
4217f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
422bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
4231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
424823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Eat ';'.
42597144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
4266869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi,
4279ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                   GNUAttr ? diag::err_expected_semi_after_attribute_list
4289ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                           : diag::err_expected_semi_after_namespace_name,
4299ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                   "", tok::semi);
430f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
43123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
4327f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                     IdentLoc, NamespcName, attrs.getList());
433f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
434f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
435162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration.
436162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// Assumes that 'using' was already seen.
437f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
438f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///     using-declaration: [C++ 7.3.p3: namespace.udecl]
439f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       'using' 'typename'[opt] ::[opt] nested-name-specifier
4409cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///               unqualified-id
4419cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///       'using' :: unqualified-id
442f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
443d03de6aaa312d57dcd6e2bc76bed1e89f5c5019dRichard Smith///     alias-declaration: C++11 [dcl.dcl]p1
444d03de6aaa312d57dcd6e2bc76bed1e89f5c5019dRichard Smith///       'using' identifier attribute-specifier-seq[opt] = type-id ;
445162e1c1b487352434552147967c3dd296ebee2f7Richard Smith///
446d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDeclaration(unsigned Context,
44778b810559d89e996e00684335407443936ce34a1John McCall                                    const ParsedTemplateInfo &TemplateInfo,
44878b810559d89e996e00684335407443936ce34a1John McCall                                    SourceLocation UsingLoc,
44978b810559d89e996e00684335407443936ce34a1John McCall                                    SourceLocation &DeclEnd,
450c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                    AccessSpecifier AS,
451c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                    Decl **OwnedType) {
4529cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  CXXScopeSpec SS;
4537ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall  SourceLocation TypenameLoc;
4546b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith  bool IsTypeName = false;
4556b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith  ParsedAttributesWithRange Attrs(AttrFactory);
4562edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
4572edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  // FIXME: Simply skip the attributes and diagnose, don't bother parsing them.
4586b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith  MaybeParseCXX11Attributes(Attrs);
4596b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith  ProhibitAttributes(Attrs);
4606b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith  Attrs.clear();
4616b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith  Attrs.Range = SourceRange();
4629cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
4639cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Ignore optional 'typename'.
46412c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // FIXME: This is wrong; we should parse this as a typename-specifier.
4659cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_typename)) {
4666b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith    TypenameLoc = ConsumeToken();
4679cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = true;
4689cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
4699cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
4709cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Parse nested-name-specifier.
471efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
4729cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
4739cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Check nested-name specifier.
4749cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (SS.isInvalid()) {
4759cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
476d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
4779cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
4781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
479193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  // Parse the unqualified-id. We allow parsing of both constructor and
48012c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // destructor names and allow the action module to diagnose any semantic
48112c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // errors.
482e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara  SourceLocation TemplateKWLoc;
48312c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  UnqualifiedId Name;
484193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  if (ParseUnqualifiedId(SS,
48512c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*EnteringContext=*/false,
48612c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*AllowDestructorName=*/true,
487193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                         /*AllowConstructorName=*/true,
488b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                         ParsedType(),
489e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                         TemplateKWLoc,
49012c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         Name)) {
4919cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
492d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
4939cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
494193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
4956b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith  MaybeParseCXX11Attributes(Attrs);
496162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
497162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  // Maybe this is an alias-declaration.
498162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  bool IsAliasDecl = Tok.is(tok::equal);
499162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  TypeResult TypeAlias;
500162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (IsAliasDecl) {
5016b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith    // TODO: Can GNU attributes appear here?
502162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    ConsumeToken();
503162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
50480ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith    Diag(Tok.getLocation(), getLangOpts().CPlusPlus11 ?
5057fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith         diag::warn_cxx98_compat_alias_declaration :
5067fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith         diag::ext_alias_declaration);
507162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
5083e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    // Type alias templates cannot be specialized.
5093e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    int SpecKind = -1;
510536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&
511536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith        Name.getKind() == UnqualifiedId::IK_TemplateId)
5123e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 0;
5133e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)
5143e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 1;
5153e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
5163e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 2;
5173e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (SpecKind != -1) {
5183e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SourceRange Range;
5193e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      if (SpecKind == 0)
5203e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        Range = SourceRange(Name.TemplateId->LAngleLoc,
5213e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                            Name.TemplateId->RAngleLoc);
5223e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      else
5233e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        Range = TemplateInfo.getSourceRange();
5243e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      Diag(Range.getBegin(), diag::err_alias_declaration_specialization)
5253e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        << SpecKind << Range;
5263e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SkipUntil(tok::semi);
5273e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      return 0;
5283e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    }
5293e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
530162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    // Name must be an identifier.
531162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    if (Name.getKind() != UnqualifiedId::IK_Identifier) {
532162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(Name.StartLocation, diag::err_alias_declaration_not_identifier);
533162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      // No removal fixit: can't recover from this.
534162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      SkipUntil(tok::semi);
535162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      return 0;
536162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    } else if (IsTypeName)
537162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(TypenameLoc, diag::err_alias_declaration_not_identifier)
538162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        << FixItHint::CreateRemoval(SourceRange(TypenameLoc,
539162e1c1b487352434552147967c3dd296ebee2f7Richard Smith                             SS.isNotEmpty() ? SS.getEndLoc() : TypenameLoc));
540162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    else if (SS.isNotEmpty())
541162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
542162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        << FixItHint::CreateRemoval(SS.getRange());
543162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
5443e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    TypeAlias = ParseTypeName(0, TemplateInfo.Kind ?
5453e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                              Declarator::AliasTemplateContext :
5466b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith                              Declarator::AliasDeclContext, AS, OwnedType,
5476b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith                              &Attrs);
5482edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  } else {
5492edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt    // C++11 attributes are not allowed on a using-declaration, but GNU ones
5502edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt    // are.
5516b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith    ProhibitAttributes(Attrs);
5522edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
553162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    // Parse (optional) attributes (most likely GNU strong-using extension).
5546b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith    MaybeParseGNUAttributes(Attrs);
5552edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  }
5561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5579cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Eat ';'.
5589cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  DeclEnd = Tok.getLocation();
5599cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
5606b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith                   !Attrs.empty() ? "attributes list" :
561162e1c1b487352434552147967c3dd296ebee2f7Richard Smith                   IsAliasDecl ? "alias declaration" : "using declaration",
56212c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                   tok::semi);
5639cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
56478b810559d89e996e00684335407443936ce34a1John McCall  // Diagnose an attempt to declare a templated using-declaration.
565d03de6aaa312d57dcd6e2bc76bed1e89f5c5019dRichard Smith  // In C++11, alias-declarations can be templates:
566162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  //   template <...> using id = type;
5673e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  if (TemplateInfo.Kind && !IsAliasDecl) {
56878b810559d89e996e00684335407443936ce34a1John McCall    SourceRange R = TemplateInfo.getSourceRange();
56978b810559d89e996e00684335407443936ce34a1John McCall    Diag(UsingLoc, diag::err_templated_using_declaration)
57078b810559d89e996e00684335407443936ce34a1John McCall      << R << FixItHint::CreateRemoval(R);
57178b810559d89e996e00684335407443936ce34a1John McCall
57278b810559d89e996e00684335407443936ce34a1John McCall    // Unfortunately, we have to bail out instead of recovering by
57378b810559d89e996e00684335407443936ce34a1John McCall    // ignoring the parameters, just in case the nested name specifier
57478b810559d89e996e00684335407443936ce34a1John McCall    // depends on the parameters.
57578b810559d89e996e00684335407443936ce34a1John McCall    return 0;
57678b810559d89e996e00684335407443936ce34a1John McCall  }
57778b810559d89e996e00684335407443936ce34a1John McCall
578480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  // "typename" keyword is allowed for identifiers only,
579480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  // because it may be a type definition.
580480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  if (IsTypeName && Name.getKind() != UnqualifiedId::IK_Identifier) {
581480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor    Diag(Name.getSourceRange().getBegin(), diag::err_typename_identifiers_only)
582480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor      << FixItHint::CreateRemoval(SourceRange(TypenameLoc));
583480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor    // Proceed parsing, but reset the IsTypeName flag.
584480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor    IsTypeName = false;
585480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  }
586480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor
5873e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  if (IsAliasDecl) {
5883e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
5895354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer    MultiTemplateParamsArg TemplateParamsArg(
5903e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      TemplateParams ? TemplateParams->data() : 0,
5913e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      TemplateParams ? TemplateParams->size() : 0);
5923e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,
5936b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith                                         UsingLoc, Name, Attrs.getList(),
5946b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith                                         TypeAlias);
5953e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
596162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
5978113ecfa4e41e2c888b1794389dfe3bce6386493Ted Kremenek  return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS,
5986b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith                                       Name, Attrs.getList(),
5997f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                       IsTypeName, TypenameLoc);
600f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
601f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
602ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer/// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration.
603511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
604c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// [C++0x] static_assert-declaration:
605c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///           static_assert ( constant-expression  ,  string-literal  ) ;
606c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///
607ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer/// [C11]   static_assert-declaration:
608c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///           _Static_assert ( constant-expression  ,  string-literal  ) ;
609511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
610d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
611c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne  assert((Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) &&
612c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne         "Not a static_assert declaration");
613c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne
6144e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11)
615ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer    Diag(Tok, diag::ext_c11_static_assert);
616841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith  if (Tok.is(tok::kw_static_assert))
617841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith    Diag(Tok, diag::warn_cxx98_compat_static_assert);
618c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne
619511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation StaticAssertLoc = ConsumeToken();
6201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6214a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
6224a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.consumeOpen()) {
623511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_lparen);
6243686c71ff92e4357a78993a16a27185f16ab6234Richard Smith    SkipMalformedDecl();
625d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
626511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
6271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62860d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult AssertExpr(ParseConstantExpression());
629511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (AssertExpr.isInvalid()) {
6303686c71ff92e4357a78993a16a27185f16ab6234Richard Smith    SkipMalformedDecl();
631d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
632511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
6331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
634ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
635d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
636ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson
6370cc323c6bed7206f9743a9775ec8d9cb90655f9cRichard Smith  if (!isTokenStringLiteral()) {
63897f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs    Diag(Tok, diag::err_expected_string_literal)
63997f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs      << /*Source='static_assert'*/1;
6403686c71ff92e4357a78993a16a27185f16ab6234Richard Smith    SkipMalformedDecl();
641d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
642511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
6431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
64460d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult AssertMessage(ParseStringLiteralExpression());
64599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  if (AssertMessage.isInvalid()) {
6463686c71ff92e4357a78993a16a27185f16ab6234Richard Smith    SkipMalformedDecl();
647d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
64899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  }
649511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
6504a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
6511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
65297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
6539ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor  ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert);
654511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
6559ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc,
6569ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                              AssertExpr.take(),
657a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                              AssertMessage.take(),
6584a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                              T.getCloseLocation());
659511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson}
660511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
6616fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// ParseDecltypeSpecifier - Parse a C++0x decltype specifier.
6626fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
6636fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 'decltype' ( expression )
6646fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
66542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid BlaikieSourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
66642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  assert((Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype))
66742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie           && "Not a decltype specifier");
66842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
6696fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
67042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  ExprResult Result;
67142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  SourceLocation StartLoc = Tok.getLocation();
67242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  SourceLocation EndLoc;
6731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
67442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  if (Tok.is(tok::annot_decltype)) {
67542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    Result = getExprAnnotation(Tok);
67642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    EndLoc = Tok.getAnnotationEndLoc();
67742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    ConsumeToken();
67842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    if (Result.isInvalid()) {
67942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      DS.SetTypeSpecError();
68042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      return EndLoc;
68142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    }
68242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  } else {
683c7b5543ad32a5c265c02e71b2a6f9856440ed13fRichard Smith    if (Tok.getIdentifierInfo()->isStr("decltype"))
684c7b5543ad32a5c265c02e71b2a6f9856440ed13fRichard Smith      Diag(Tok, diag::warn_cxx98_compat_decltype);
68539304fad1c8a7b7e64121e9ae544b18e460b682cRichard Smith
68642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    ConsumeToken();
6871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    BalancedDelimiterTracker T(*this, tok::l_paren);
68942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    if (T.expectAndConsume(diag::err_expected_lparen_after,
69042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie                           "decltype", tok::r_paren)) {
69142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      DS.SetTypeSpecError();
69242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      return T.getOpenLocation() == Tok.getLocation() ?
69342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie             StartLoc : T.getOpenLocation();
69442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    }
6951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
69642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    // Parse the expression
69742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
69842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    // C++0x [dcl.type.simple]p4:
69942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    //   The operand of the decltype specifier is an unevaluated operand.
70076f3f69db1416425070177243e9f390122c553e0Richard Smith    EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
70176f3f69db1416425070177243e9f390122c553e0Richard Smith                                                 0, /*IsDecltype=*/true);
70242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    Result = ParseExpression();
70342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    if (Result.isInvalid()) {
70442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      DS.SetTypeSpecError();
7051e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis      if (SkipUntil(tok::r_paren, /*StopAtSemi=*/true, /*DontConsume=*/true)) {
7061e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis        EndLoc = ConsumeParen();
7071e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis      } else {
708569cdc82c1a99fe1e950a1ddbe5ff82df0b13f3dRichard Smith        if (PP.isBacktrackEnabled() && Tok.is(tok::semi)) {
7091e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis          // Backtrack to get the location of the last token before the semi.
7101e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis          PP.RevertCachedTokens(2);
7111e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis          ConsumeToken(); // the semi.
7121e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis          EndLoc = ConsumeAnyToken();
7131e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis          assert(Tok.is(tok::semi));
7141e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis        } else {
7151e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis          EndLoc = Tok.getLocation();
7161e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis        }
7171e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis      }
7181e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis      return EndLoc;
71942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    }
72042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
72142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    // Match the ')'
72242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    T.consumeClose();
72342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    if (T.getCloseLocation().isInvalid()) {
72442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      DS.SetTypeSpecError();
72542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      // FIXME: this should return the location of the last token
72642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      //        that was consumed (by "consumeClose()")
72742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      return T.getCloseLocation();
72842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    }
72942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
73076f3f69db1416425070177243e9f390122c553e0Richard Smith    Result = Actions.ActOnDecltypeExpression(Result.take());
73176f3f69db1416425070177243e9f390122c553e0Richard Smith    if (Result.isInvalid()) {
73276f3f69db1416425070177243e9f390122c553e0Richard Smith      DS.SetTypeSpecError();
73376f3f69db1416425070177243e9f390122c553e0Richard Smith      return T.getCloseLocation();
73476f3f69db1416425070177243e9f390122c553e0Richard Smith    }
73576f3f69db1416425070177243e9f390122c553e0Richard Smith
73642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    EndLoc = T.getCloseLocation();
73742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  }
7386fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
7396fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  const char *PrevSpec = 0;
740fec54013fcd0eb72642741584ca04c1bc292bef8John McCall  unsigned DiagID;
7416fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Check for duplicate type specifiers (e.g. "int decltype(a)").
7421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec,
74342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie                         DiagID, Result.release())) {
744fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
74542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    DS.SetTypeSpecError();
74642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  }
74742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  return EndLoc;
74842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie}
74942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
75042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikievoid Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec& DS,
75142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie                                               SourceLocation StartLoc,
75242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie                                               SourceLocation EndLoc) {
75342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  // make sure we have a token we can turn into an annotation token
75442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  if (PP.isBacktrackEnabled())
75542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    PP.RevertCachedTokens(1);
75642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  else
75742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    PP.EnterToken(Tok);
75842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
75942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  Tok.setKind(tok::annot_decltype);
76042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  setExprAnnotation(Tok, DS.getTypeSpecType() == TST_decltype ?
76142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie                         DS.getRepAsExpr() : ExprResult());
76242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  Tok.setAnnotationEndLoc(EndLoc);
76342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  Tok.setLocation(StartLoc);
76442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  PP.AnnotateCachedTokens(Tok);
7656fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson}
7666fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
767db5d44b775c60166074acd184ca9f1981c10c2a7Sean Huntvoid Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) {
768db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  assert(Tok.is(tok::kw___underlying_type) &&
769db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt         "Not an underlying type specifier");
770db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
771db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  SourceLocation StartLoc = ConsumeToken();
7724a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
7734a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.expectAndConsume(diag::err_expected_lparen_after,
7744a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                       "__underlying_type", tok::r_paren)) {
775db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
776db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  }
777db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
778db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  TypeResult Result = ParseTypeName();
779db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  if (Result.isInvalid()) {
780db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    SkipUntil(tok::r_paren);
781db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
782db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  }
783db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
784db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  // Match the ')'
7854a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
7864a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.getCloseLocation().isInvalid())
787db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
788db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
789db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  const char *PrevSpec = 0;
790db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  unsigned DiagID;
791ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec,
792db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt                         DiagID, Result.release()))
793db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    Diag(StartLoc, DiagID) << PrevSpec;
794db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt}
795db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
79609048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// ParseBaseTypeSpecifier - Parse a C++ base-type-specifier which is either a
79709048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class name or decltype-specifier. Note that we only check that the result
79809048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// names a type; semantic analysis will need to verify that the type names a
79909048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class. The result is either a type or null, depending on whether a type
80009048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// name was found.
80142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///
802053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///       base-type-specifier: [C++11 class.derived]
80309048df0b3f472091b2204e531d6b6019244884bDavid Blaikie///         class-or-decltype
804053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///       class-or-decltype: [C++11 class.derived]
80509048df0b3f472091b2204e531d6b6019244884bDavid Blaikie///         nested-name-specifier[opt] class-name
80609048df0b3f472091b2204e531d6b6019244884bDavid Blaikie///         decltype-specifier
807053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///       class-name: [C++ class.name]
80842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///         identifier
8097f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor///         simple-template-id
8101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
811053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// In C++98, instead of base-type-specifier, we have:
812053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///
813053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///         ::[opt] nested-name-specifier[opt] class-name
81422216eb4fb0936d2488fc03abd285d135c36ff01David BlaikieParser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
81522216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie                                                  SourceLocation &EndLocation) {
8167fe3878a36750515fb9772414ecb2489cf149d19David Blaikie  // Ignore attempts to use typename
8177fe3878a36750515fb9772414ecb2489cf149d19David Blaikie  if (Tok.is(tok::kw_typename)) {
8187fe3878a36750515fb9772414ecb2489cf149d19David Blaikie    Diag(Tok, diag::err_expected_class_name_not_template)
8197fe3878a36750515fb9772414ecb2489cf149d19David Blaikie      << FixItHint::CreateRemoval(Tok.getLocation());
8207fe3878a36750515fb9772414ecb2489cf149d19David Blaikie    ConsumeToken();
8217fe3878a36750515fb9772414ecb2489cf149d19David Blaikie  }
8227fe3878a36750515fb9772414ecb2489cf149d19David Blaikie
823152aa4b87633754801598ee282e1a17c3ec49257David Blaikie  // Parse optional nested-name-specifier
824152aa4b87633754801598ee282e1a17c3ec49257David Blaikie  CXXScopeSpec SS;
825152aa4b87633754801598ee282e1a17c3ec49257David Blaikie  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
826152aa4b87633754801598ee282e1a17c3ec49257David Blaikie
827152aa4b87633754801598ee282e1a17c3ec49257David Blaikie  BaseLoc = Tok.getLocation();
828152aa4b87633754801598ee282e1a17c3ec49257David Blaikie
82922216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie  // Parse decltype-specifier
83042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  // tok == kw_decltype is just error recovery, it can only happen when SS
83142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  // isn't empty
83242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  if (Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) {
833152aa4b87633754801598ee282e1a17c3ec49257David Blaikie    if (SS.isNotEmpty())
834152aa4b87633754801598ee282e1a17c3ec49257David Blaikie      Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype)
835152aa4b87633754801598ee282e1a17c3ec49257David Blaikie        << FixItHint::CreateRemoval(SS.getRange());
83622216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie    // Fake up a Declarator to use with ActOnTypeName.
83722216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie    DeclSpec DS(AttrFactory);
83822216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie
839b57775709666e50cd925f9fc589d0fd895fc79a6David Blaikie    EndLocation = ParseDecltypeSpecifier(DS);
84022216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie
84122216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie    Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
84222216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie    return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
84322216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie  }
84422216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie
8457f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  // Check whether we have a template-id that names a type.
8467f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  if (Tok.is(tok::annot_template_id)) {
84725a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
848d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor    if (TemplateId->Kind == TNK_Type_template ||
849d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor        TemplateId->Kind == TNK_Dependent_template_name) {
850059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
8517f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
8527f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
853b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      ParsedType Type = getTypeAnnotation(Tok);
8547f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      EndLocation = Tok.getAnnotationEndLoc();
8557f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      ConsumeToken();
85631a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor
85731a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      if (Type)
85831a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor        return Type;
85931a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      return true;
8607f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    }
8617f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
8627f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    // Fall through to produce an error below.
8637f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  }
8647f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
86542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  if (Tok.isNot(tok::identifier)) {
8661ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_class_name);
86731a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
86842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
86942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
87084d0a19828599e8623223632d59447fd498999cfDouglas Gregor  IdentifierInfo *Id = Tok.getIdentifierInfo();
87184d0a19828599e8623223632d59447fd498999cfDouglas Gregor  SourceLocation IdLoc = ConsumeToken();
87284d0a19828599e8623223632d59447fd498999cfDouglas Gregor
87384d0a19828599e8623223632d59447fd498999cfDouglas Gregor  if (Tok.is(tok::less)) {
87484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // It looks the user intended to write a template-id here, but the
87584d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // template-name was wrong. Try to fix that.
87684d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateNameKind TNK = TNK_Type_template;
87784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateTy Template;
87823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(),
879059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                             &SS, Template, TNK)) {
88084d0a19828599e8623223632d59447fd498999cfDouglas Gregor      Diag(IdLoc, diag::err_unknown_template_name)
88184d0a19828599e8623223632d59447fd498999cfDouglas Gregor        << Id;
88284d0a19828599e8623223632d59447fd498999cfDouglas Gregor    }
883193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
88484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (!Template)
88584d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
88684d0a19828599e8623223632d59447fd498999cfDouglas Gregor
887193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam    // Form the template name
88884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    UnqualifiedId TemplateName;
88984d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateName.setIdentifier(Id, IdLoc);
890193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
89184d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // Parse the full template-id, then turn it into a type.
892e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
893e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                                TemplateName, true))
89484d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
89584d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (TNK == TNK_Dependent_template_name)
896059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
897193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
89884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // If we didn't end up with a typename token, there's nothing more we
89984d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // can do.
90084d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (Tok.isNot(tok::annot_typename))
90184d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
902193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
90384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // Retrieve the type from the annotation token, consume that token, and
90484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // return.
90584d0a19828599e8623223632d59447fd498999cfDouglas Gregor    EndLocation = Tok.getAnnotationEndLoc();
906b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    ParsedType Type = getTypeAnnotation(Tok);
90784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    ConsumeToken();
90884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    return Type;
90984d0a19828599e8623223632d59447fd498999cfDouglas Gregor  }
91084d0a19828599e8623223632d59447fd498999cfDouglas Gregor
91142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // We have an identifier; check whether it is actually a type.
912c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain  IdentifierInfo *CorrectedII = 0;
913059101f922de6eb765601459925f4c8914420b23Douglas Gregor  ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true,
9149e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor                                        false, ParsedType(),
915fad03b75e0297546c5d12ec420b5b79d5b7baa2aAbramo Bagnara                                        /*IsCtorOrDtorName=*/false,
916c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain                                        /*NonTrivialTypeSourceInfo=*/true,
917c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain                                        &CorrectedII);
918193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  if (!Type) {
919124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor    Diag(IdLoc, diag::err_expected_class_name);
92031a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
92142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
92242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
92342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Consume the identifier.
92484d0a19828599e8623223632d59447fd498999cfDouglas Gregor  EndLocation = IdLoc;
9255606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
9265606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  // Fake up a Declarator to use with ActOnTypeName.
9270b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  DeclSpec DS(AttrFactory);
9285606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetRangeStart(IdLoc);
9295606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetRangeEnd(EndLocation);
930059101f922de6eb765601459925f4c8914420b23Douglas Gregor  DS.getTypeSpecScope() = SS;
9315606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
9325606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  const char *PrevSpec = 0;
9335606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  unsigned DiagID;
9345606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type);
9355606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
9365606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
9375606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
93842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor}
93942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
940c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallvoid Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {
941c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  while (Tok.is(tok::kw___single_inheritance) ||
942c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall         Tok.is(tok::kw___multiple_inheritance) ||
943c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall         Tok.is(tok::kw___virtual_inheritance)) {
944c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    IdentifierInfo *AttrName = Tok.getIdentifierInfo();
945c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    SourceLocation AttrNameLoc = ConsumeToken();
946c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
94793f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt                 SourceLocation(), 0, 0, AttributeList::AS_GNU);
948c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  }
949c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall}
950c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall
951c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// Determine whether the following tokens are valid after a type-specifier
952c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// which could be a standalone declaration. This will conservatively return
953c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// true if there's any doubt, and is appropriate for insert-';' fixits.
954139be7007eba3bd491ca50297888be507753a95dRichard Smithbool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
955c9f351700721150a985f21844fbfec55b04e861dRichard Smith  // This switch enumerates the valid "follow" set for type-specifiers.
956c9f351700721150a985f21844fbfec55b04e861dRichard Smith  switch (Tok.getKind()) {
957c9f351700721150a985f21844fbfec55b04e861dRichard Smith  default: break;
958c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::semi:               // struct foo {...} ;
959c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::star:               // struct foo {...} *         P;
960c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::amp:                // struct foo {...} &         R = ...
961ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  case tok::ampamp:             // struct foo {...} &&        R = ...
962c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::identifier:         // struct foo {...} V         ;
963c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::r_paren:            //(struct foo {...} )         {4}
964c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::annot_cxxscope:     // struct foo {...} a::       b;
965c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::annot_typename:     // struct foo {...} a         ::b;
966c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::annot_template_id:  // struct foo {...} a<int>    ::b;
967c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::l_paren:            // struct foo {...} (         x);
968c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::comma:              // __builtin_offsetof(struct foo{...} ,
969ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  case tok::kw_operator:        // struct foo       operator  ++() {...}
970c9f351700721150a985f21844fbfec55b04e861dRichard Smith    return true;
971139be7007eba3bd491ca50297888be507753a95dRichard Smith  case tok::colon:
972139be7007eba3bd491ca50297888be507753a95dRichard Smith    return CouldBeBitfield;     // enum E { ... }   :         2;
973c9f351700721150a985f21844fbfec55b04e861dRichard Smith  // Type qualifiers
974c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_const:           // struct foo {...} const     x;
975c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_volatile:        // struct foo {...} volatile  x;
976c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_restrict:        // struct foo {...} restrict  x;
977ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  // Function specifiers
978ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  // Note, no 'explicit'. An explicit function must be either a conversion
979ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  // operator or a constructor. Either way, it can't have a return type.
980ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  case tok::kw_inline:          // struct foo       inline    f();
981ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  case tok::kw_virtual:         // struct foo       virtual   f();
982ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  case tok::kw_friend:          // struct foo       friend    f();
983c9f351700721150a985f21844fbfec55b04e861dRichard Smith  // Storage-class specifiers
984c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_static:          // struct foo {...} static    x;
985c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_extern:          // struct foo {...} extern    x;
986c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_typedef:         // struct foo {...} typedef   x;
987c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_register:        // struct foo {...} register  x;
988c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_auto:            // struct foo {...} auto      x;
989c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_mutable:         // struct foo {...} mutable   x;
990ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  case tok::kw_thread_local:    // struct foo {...} thread_local x;
991c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_constexpr:       // struct foo {...} constexpr x;
992c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // As shown above, type qualifiers and storage class specifiers absolutely
993c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // can occur after class specifiers according to the grammar.  However,
994c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // almost no one actually writes code like this.  If we see one of these,
995c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // it is much more likely that someone missed a semi colon and the
996c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // type/storage class specifier we're seeing is part of the *next*
997c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // intended declaration, as in:
998c9f351700721150a985f21844fbfec55b04e861dRichard Smith    //
999c9f351700721150a985f21844fbfec55b04e861dRichard Smith    //   struct foo { ... }
1000c9f351700721150a985f21844fbfec55b04e861dRichard Smith    //   typedef int X;
1001c9f351700721150a985f21844fbfec55b04e861dRichard Smith    //
1002c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // We'd really like to emit a missing semicolon error instead of emitting
1003c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // an error on the 'int' saying that you can't have two type specifiers in
1004c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // the same declaration of X.  Because of this, we look ahead past this
1005c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // token to see if it's a type specifier.  If so, we know the code is
1006c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // otherwise invalid, so we can produce the expected semi error.
1007c9f351700721150a985f21844fbfec55b04e861dRichard Smith    if (!isKnownToBeTypeSpecifier(NextToken()))
1008c9f351700721150a985f21844fbfec55b04e861dRichard Smith      return true;
1009c9f351700721150a985f21844fbfec55b04e861dRichard Smith    break;
1010c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::r_brace:  // struct bar { struct foo {...} }
1011c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // Missing ';' at end of struct is accepted as an extension in C mode.
1012c9f351700721150a985f21844fbfec55b04e861dRichard Smith    if (!getLangOpts().CPlusPlus)
1013c9f351700721150a985f21844fbfec55b04e861dRichard Smith      return true;
1014c9f351700721150a985f21844fbfec55b04e861dRichard Smith    break;
1015ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith    // C++11 attributes
1016ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  case tok::l_square: // enum E [[]] x
1017ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith    // Note, no tok::kw_alignas here; alignas cannot appertain to a type.
1018ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith    return getLangOpts().CPlusPlus11 && NextToken().is(tok::l_square);
10198338a9d28c4a9d06b19b1c5df51e70182914e2dfRichard Smith  case tok::greater:
10208338a9d28c4a9d06b19b1c5df51e70182914e2dfRichard Smith    // template<class T = class X>
10218338a9d28c4a9d06b19b1c5df51e70182914e2dfRichard Smith    return getLangOpts().CPlusPlus;
1022c9f351700721150a985f21844fbfec55b04e861dRichard Smith  }
1023c9f351700721150a985f21844fbfec55b04e861dRichard Smith  return false;
1024c9f351700721150a985f21844fbfec55b04e861dRichard Smith}
1025c9f351700721150a985f21844fbfec55b04e861dRichard Smith
1026e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
1027e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
1028e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that
102969730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith/// cannot start a definition.
1030e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1031e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-specifier: [C++ class]
1032e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}'
1033e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}' attributes[opt]
1034e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-head:
1035e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key identifier[opt] base-clause[opt]
1036e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier identifier base-clause[opt]
1037e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier[opt] simple-template-id
1038e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          base-clause[opt]
1039e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   class-key attributes[opt] identifier[opt] base-clause[opt]
10401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier
1041e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          identifier base-clause[opt]
10421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier[opt]
1043e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          simple-template-id base-clause[opt]
1044e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-key:
1045e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'class'
1046e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
1047e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
1048e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1049e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       elaborated-type-specifier: [C++ dcl.type.elab]
10501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] identifier
10511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
10521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///                          simple-template-id
1053e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1054e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  Note that the C++ class-specifier and elaborated-type-specifier,
1055e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  together, subsume the C99 struct-or-union-specifier:
1056e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1057e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union-specifier: [C99 6.7.2.1]
1058e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier[opt] '{' struct-contents '}'
1059e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier
1060e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier[opt] '{' struct-contents
1061e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                                                         '}' attributes[opt]
1062e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier
1063e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union:
1064e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
1065e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
10664c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattnervoid Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
10674c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner                                 SourceLocation StartLoc, DeclSpec &DS,
10684d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                 const ParsedTemplateInfo &TemplateInfo,
1069efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor                                 AccessSpecifier AS,
10702e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han                                 bool EnteringContext, DeclSpecContext DSC,
1071ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling                                 ParsedAttributesWithRange &Attributes) {
107217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos  DeclSpec::TST TagType;
107317d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos  if (TagTokKind == tok::kw_struct)
107417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos    TagType = DeclSpec::TST_struct;
107517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos  else if (TagTokKind == tok::kw___interface)
107617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos    TagType = DeclSpec::TST_interface;
107717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos  else if (TagTokKind == tok::kw_class)
107817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos    TagType = DeclSpec::TST_class;
107917d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos  else {
10804c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    assert(TagTokKind == tok::kw_union && "Not a class specifier");
10814c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_union;
10824c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  }
1083e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1084374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  if (Tok.is(tok::code_completion)) {
1085374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor    // Code completion for a struct, class, or union name.
108623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteTag(getCurScope(), TagType);
10877d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return cutOffParsing();
1088374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  }
1089193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1090926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // C++03 [temp.explicit] 14.7.2/8:
1091926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //   The usual access checking rules do not apply to names used to specify
1092926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //   explicit instantiations.
1093926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //
1094926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // As an extension we do not perform access checking on the names used to
1095926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // specify explicit specializations either. This is important to allow
1096926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // specializing traits classes for private types.
109713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  //
109813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  // Note that we don't suppress if this turns out to be an elaborated
109913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  // type specifier.
110013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  bool shouldDelayDiagsInTag =
110113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
110213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall     TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
110313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
1104926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
11052edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  ParsedAttributesWithRange attrs(AttrFactory);
1106e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If attributes exist after tag, parse them.
1107e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw___attribute))
11087f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
1109e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1110f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff  // If declspecs exist after tag, parse them.
1111b1d397c23e1f8fd8b404d5731d531e7500f7140dJohn McCall  while (Tok.is(tok::kw___declspec))
11127f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseMicrosoftDeclSpec(attrs);
1113193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1114c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  // Parse inheritance specifiers.
1115c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  if (Tok.is(tok::kw___single_inheritance) ||
1116c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      Tok.is(tok::kw___multiple_inheritance) ||
1117c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      Tok.is(tok::kw___virtual_inheritance))
1118c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      ParseMicrosoftInheritanceClassAttributes(attrs);
1119c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall
1120bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // If C++0x attributes exist here, parse them.
1121bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Are we consistent with the ordering of parsing of different
1122bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // styles of attributes?
11234e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith  MaybeParseCXX11Attributes(attrs);
11241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
112507fc1ba7553f2f5bf26984091197311decd9028eMichael Han  // Source location used by FIXIT to insert misplaced
112607fc1ba7553f2f5bf26984091197311decd9028eMichael Han  // C++11 attributes
112707fc1ba7553f2f5bf26984091197311decd9028eMichael Han  SourceLocation AttrFixitLoc = Tok.getLocation();
112807fc1ba7553f2f5bf26984091197311decd9028eMichael Han
112920c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley  if (TagType == DeclSpec::TST_struct &&
1130b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      !Tok.is(tok::identifier) &&
1131b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      Tok.getIdentifierInfo() &&
1132b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      (Tok.is(tok::kw___is_arithmetic) ||
1133b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_convertible) ||
113420c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley       Tok.is(tok::kw___is_empty) ||
1135b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_floating_point) ||
1136b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_function) ||
113720c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley       Tok.is(tok::kw___is_fundamental) ||
1138b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_integral) ||
1139b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_member_function_pointer) ||
1140b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_member_pointer) ||
1141b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_pod) ||
1142b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_pointer) ||
1143b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_same) ||
1144877222e2491bbc40a5c74cc100c540983f306b70Douglas Gregor       Tok.is(tok::kw___is_scalar) ||
1145b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_signed) ||
1146b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_unsigned) ||
1147b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_void))) {
1148688761409155b47c39eb5dae1b8c6c8a9f43307aDouglas Gregor    // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the
1149b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // name of struct templates, but some are keywords in GCC >= 4.3
1150b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // and Clang. Therefore, when we see the token sequence "struct
1151b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // X", make X into a normal identifier rather than a keyword, to
1152b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // allow libstdc++ 4.2 and libc++ to work properly.
1153646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
1154b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.setKind(tok::identifier);
1155b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  }
11561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1157eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse the (optional) nested-name-specifier.
1158aa87d33309f505b68c3bfc17486c93e4d224b24fJohn McCall  CXXScopeSpec &SS = DS.getTypeSpecScope();
11594e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().CPlusPlus) {
116008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    // "FOO : BAR" is not a potential typo for "FOO::BAR".
116108d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    ColonProtectionRAIIObject X(*this);
1162193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1163efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor    if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext))
1164207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      DS.SetTypeSpecError();
11659ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall    if (SS.isSet())
116608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner      if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
116708d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner        Diag(Tok, diag::err_expected_ident);
116808d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  }
1169cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
11702cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor  TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
11712cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor
1172cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  // Parse the (optional) class name or simple-template-id.
1173e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  IdentifierInfo *Name = 0;
1174e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation NameLoc;
117539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  TemplateIdAnnotation *TemplateId = 0;
1176e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::identifier)) {
1177e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    Name = Tok.getIdentifierInfo();
1178e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    NameLoc = ConsumeToken();
1179193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
11804e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (Tok.is(tok::less) && getLangOpts().CPlusPlus) {
1181193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      // The name was supposed to refer to a template, but didn't.
11822cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // Eat the template argument list and try to continue parsing this as
11832cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // a class (or template thereof).
11842cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      TemplateArgList TemplateArgs;
11852cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      SourceLocation LAngleLoc, RAngleLoc;
1186059101f922de6eb765601459925f4c8914420b23Douglas Gregor      if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, SS,
11872cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor                                           true, LAngleLoc,
1188314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor                                           TemplateArgs, RAngleLoc)) {
11892cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // We couldn't parse the template argument list at all, so don't
11902cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // try to give any location information for the list.
11912cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        LAngleLoc = RAngleLoc = SourceLocation();
11922cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
1193193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
11942cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      Diag(NameLoc, diag::err_explicit_spec_non_template)
119517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos        << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
119617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos        << (TagType == DeclSpec::TST_class? 0
119717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos            : TagType == DeclSpec::TST_struct? 1
119817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos            : TagType == DeclSpec::TST_interface? 2
119917d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos            : 3)
120017d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos        << Name
120117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos        << SourceRange(LAngleLoc, RAngleLoc);
120217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos
1203193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      // Strip off the last template parameter list if it was empty, since
1204c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      // we've removed its template argument list.
1205c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
1206c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        if (TemplateParams && TemplateParams->size() > 1) {
1207c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams->pop_back();
1208c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        } else {
1209c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams = 0;
1210193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam          const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
1211c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor            = ParsedTemplateInfo::NonTemplate;
1212c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        }
1213c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      } else if (TemplateInfo.Kind
1214c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor                                == ParsedTemplateInfo::ExplicitInstantiation) {
1215c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        // Pretend this is just a forward declaration.
12162cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        TemplateParams = 0;
1217193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam        const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
12182cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor          = ParsedTemplateInfo::NonTemplate;
1219193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam        const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc
1220c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
1221c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc
1222c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
12232cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
12242cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor    }
122539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  } else if (Tok.is(tok::annot_template_id)) {
122625a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis    TemplateId = takeTemplateIdAnnotation(Tok);
122739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    NameLoc = ConsumeToken();
1228cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
1229059101f922de6eb765601459925f4c8914420b23Douglas Gregor    if (TemplateId->Kind != TNK_Type_template &&
1230059101f922de6eb765601459925f4c8914420b23Douglas Gregor        TemplateId->Kind != TNK_Dependent_template_name) {
123139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // The template-name in the simple-template-id refers to
123239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // something other than a class template. Give an appropriate
123339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // error message and skip to the ';'.
123439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SourceRange Range(NameLoc);
123539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      if (SS.isNotEmpty())
123639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        Range.setBegin(SS.getBeginLoc());
123739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
123839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
123939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        << Name << static_cast<int>(TemplateId->Kind) << Range;
12401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
124139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      DS.SetTypeSpecError();
124239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SkipUntil(tok::semi, false, true);
124339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      return;
1244cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    }
1245e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1246e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
12477796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  // There are four options here.
12487796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //  - If we are in a trailing return type, this is always just a reference,
12497796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //    and we must not try to parse a definition. For instance,
12507796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //      [] () -> struct S { };
12517796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //    does not define a type.
12527796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //  - If we have 'struct foo {...', 'struct foo :...',
12537796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //    'struct foo final :' or 'struct foo final {', then this is a definition.
12547796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //  - If we have 'struct foo;', then this is either a forward declaration
12557796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //    or a friend declaration, which have to be treated differently.
12567796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //  - Otherwise we have something like 'struct foo xyz', a reference.
12572e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //
12582e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //  We also detect these erroneous cases to provide better diagnostic for
12592e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //  C++11 attributes parsing.
12602e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //  - attributes follow class name:
12612e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //    struct foo [[]] {};
12622e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //  - attributes appear before or after 'final':
12632e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //    struct foo [[]] final [[]] {};
12642e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //
126569730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  // However, in type-specifier-seq's, things look like declarations but are
126669730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  // just references, e.g.
126769730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  //   new struct s;
1268d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // or
126969730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  //   &T::operator struct s;
127069730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  // For these, DSC is DSC_type_specifier.
12712e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
12722e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  // If there are attributes after class name, parse them.
12734e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith  MaybeParseCXX11Attributes(Attributes);
12742e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
1275f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  Sema::TagUseKind TUK;
12767796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  if (DSC == DSC_trailing)
12777796eb5643244f3134834253ce5ea89107ac21c1Richard Smith    TUK = Sema::TUK_Reference;
12787796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  else if (Tok.is(tok::l_brace) ||
12797796eb5643244f3134834253ce5ea89107ac21c1Richard Smith           (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
12804e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith           (isCXX11FinalKeyword() &&
12816f42669b7c0b81b07a15a0483aa5e897ce57cb45David Blaikie            (NextToken().is(tok::l_brace) || NextToken().is(tok::colon)))) {
1282d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    if (DS.isFriendSpecified()) {
1283d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // C++ [class.friend]p2:
1284d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      //   A class shall not be defined in a friend declaration.
1285bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith      Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
1286d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor        << SourceRange(DS.getFriendSpecLoc());
1287d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor
1288d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Skip everything up to the semicolon, so that this looks like a proper
1289d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // friend class (or template thereof) declaration.
1290d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      SkipUntil(tok::semi, true, true);
1291f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall      TUK = Sema::TUK_Friend;
1292d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    } else {
1293d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Okay, this is a class definition.
1294f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall      TUK = Sema::TUK_Definition;
1295d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    }
1296150d853343758281f7b0c44e058ea81da45b79beRichard Smith  } else if (isCXX11FinalKeyword() && (NextToken().is(tok::l_square) ||
1297150d853343758281f7b0c44e058ea81da45b79beRichard Smith                                       NextToken().is(tok::kw_alignas))) {
12982e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    // We can't tell if this is a definition or reference
12992e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    // until we skipped the 'final' and C++11 attribute specifiers.
13002e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    TentativeParsingAction PA(*this);
13012e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
13022e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    // Skip the 'final' keyword.
13032e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    ConsumeToken();
13042e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
13052e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    // Skip C++11 attribute specifiers.
13062e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    while (true) {
13072e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han      if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {
13082e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han        ConsumeBracket();
13092e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han        if (!SkipUntil(tok::r_square))
13102e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han          break;
1311150d853343758281f7b0c44e058ea81da45b79beRichard Smith      } else if (Tok.is(tok::kw_alignas) && NextToken().is(tok::l_paren)) {
13122e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han        ConsumeToken();
13132e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han        ConsumeParen();
13142e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han        if (!SkipUntil(tok::r_paren))
13152e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han          break;
13162e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han      } else {
13172e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han        break;
13182e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han      }
13192e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    }
13202e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
13212e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    if (Tok.is(tok::l_brace) || Tok.is(tok::colon))
13222e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han      TUK = Sema::TUK_Definition;
13232e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    else
13242e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han      TUK = Sema::TUK_Reference;
13252e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
13262e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    PA.Revert();
1327c9f351700721150a985f21844fbfec55b04e861dRichard Smith  } else if (DSC != DSC_type_specifier &&
1328c9f351700721150a985f21844fbfec55b04e861dRichard Smith             (Tok.is(tok::semi) ||
1329139be7007eba3bd491ca50297888be507753a95dRichard Smith              (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) {
1330f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
133117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos    if (Tok.isNot(tok::semi)) {
133217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos      // A semicolon was missing after this declaration. Diagnose and recover.
133317d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
133417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos        DeclSpec::getSpecifierName(TagType));
133517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos      PP.EnterToken(Tok);
133617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos      Tok.setKind(tok::semi);
133717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos    }
1338c9f351700721150a985f21844fbfec55b04e861dRichard Smith  } else
1339f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = Sema::TUK_Reference;
1340e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
13412e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  // Forbid misplaced attributes. In cases of a reference, we pass attributes
13422e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  // to caller to handle.
134307fc1ba7553f2f5bf26984091197311decd9028eMichael Han  if (TUK != Sema::TUK_Reference) {
134407fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // If this is not a reference, then the only possible
134507fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // valid place for C++11 attributes to appear here
134607fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // is between class-key and class-name. If there are
134707fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // any attributes after class-name, we try a fixit to move
134807fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // them to the right place.
134907fc1ba7553f2f5bf26984091197311decd9028eMichael Han    SourceRange AttrRange = Attributes.Range;
135007fc1ba7553f2f5bf26984091197311decd9028eMichael Han    if (AttrRange.isValid()) {
135107fc1ba7553f2f5bf26984091197311decd9028eMichael Han      Diag(AttrRange.getBegin(), diag::err_attributes_not_allowed)
135207fc1ba7553f2f5bf26984091197311decd9028eMichael Han        << AttrRange
135307fc1ba7553f2f5bf26984091197311decd9028eMichael Han        << FixItHint::CreateInsertionFromRange(AttrFixitLoc,
135407fc1ba7553f2f5bf26984091197311decd9028eMichael Han                                               CharSourceRange(AttrRange, true))
135507fc1ba7553f2f5bf26984091197311decd9028eMichael Han        << FixItHint::CreateRemoval(AttrRange);
135607fc1ba7553f2f5bf26984091197311decd9028eMichael Han
135707fc1ba7553f2f5bf26984091197311decd9028eMichael Han      // Recover by adding misplaced attributes to the attribute list
135807fc1ba7553f2f5bf26984091197311decd9028eMichael Han      // of the class so they can be applied on the class later.
135907fc1ba7553f2f5bf26984091197311decd9028eMichael Han      attrs.takeAllFrom(Attributes);
136007fc1ba7553f2f5bf26984091197311decd9028eMichael Han    }
136107fc1ba7553f2f5bf26984091197311decd9028eMichael Han  }
13622e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
136313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  // If this is an elaborated type specifier, and we delayed
136413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  // diagnostics before, just merge them into the current pool.
136513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  if (shouldDelayDiagsInTag) {
136613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    diagsFromTag.done();
136713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    if (TUK == Sema::TUK_Reference)
136813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      diagsFromTag.redelay();
136913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  }
137013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall
1371207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall  if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error ||
1372f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                               TUK != Sema::TUK_Definition)) {
1373207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall    if (DS.getTypeSpecType() != DeclSpec::TST_error) {
1374207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      // We have a declaration or reference to an anonymous class.
1375207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      Diag(StartLoc, diag::err_anon_type_definition)
1376207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall        << DeclSpec::getSpecifierName(TagType);
1377207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall    }
1378e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1379e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SkipUntil(tok::comma, true);
1380e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    return;
1381e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1382e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1383ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  // Create the tag portion of the class or class template.
1384d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  DeclResult TagOrTempResult = true; // invalid
1385d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  TypeResult TypeResult = true; // invalid
13864d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
1387402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor  bool Owned = false;
1388f1bbbb49f06a7462476cd88166fccda5feb15cabJohn McCall  if (TemplateId) {
13894d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // Explicit specialization, class template partial specialization,
13904d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // or explicit instantiation.
13915354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer    ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
139239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->NumArgs);
13934d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1394f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        TUK == Sema::TUK_Declaration) {
13954d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit instantiation of a class template.
13962edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt      ProhibitAttributes(attrs);
13972edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
13984d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
139923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        = Actions.ActOnExplicitInstantiation(getCurScope(),
140045f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                             TemplateInfo.ExternLoc,
14011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateInfo.TemplateLoc,
14024d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TagType,
14031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             StartLoc,
14044d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             SS,
14052b5289b6fd7e3d9899868410a498c081c9595662John McCall                                             TemplateId->Template,
14061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->TemplateNameLoc,
14071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->LAngleLoc,
14084d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateArgsPtr,
14091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->RAngleLoc,
14107f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                             attrs.getList());
141174256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall
141274256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // Friend template-ids are treated as references unless
141374256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // they have template headers, in which case they're ill-formed
141474256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // (FIXME: "template <class T> friend class A<T>::B<int>;").
141574256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // We diagnose this error in ActOnClassTemplateSpecialization.
1416f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    } else if (TUK == Sema::TUK_Reference ||
1417f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall               (TUK == Sema::TUK_Friend &&
141874256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall                TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
14192edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt      ProhibitAttributes(attrs);
142055d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara      TypeResult = Actions.ActOnTagTemplateIdType(TUK, TagType, StartLoc,
1421059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->SS,
142255d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara                                                  TemplateId->TemplateKWLoc,
1423059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->Template,
1424059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->TemplateNameLoc,
1425059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->LAngleLoc,
1426059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateArgsPtr,
142755d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara                                                  TemplateId->RAngleLoc);
14284d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    } else {
14294d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit specialization or a class template
14304d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // partial specialization.
14314d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TemplateParameterLists FakedParamLists;
14324d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
14334d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
14344d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // This looks like an explicit instantiation, because we have
14354d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // something like
14364d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
14374d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //   template class Foo<X>
14384d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
14393f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor        // but it actually has a definition. Most likely, this was
14404d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // meant to be an explicit specialization, but the user forgot
14414d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // the '<>' after 'template'.
1442f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        assert(TUK == Sema::TUK_Definition && "Expected a definition here");
14434d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
14441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        SourceLocation LAngleLoc
14454d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
14461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        Diag(TemplateId->TemplateNameLoc,
14474d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor             diag::err_explicit_instantiation_with_definition)
14484d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          << SourceRange(TemplateInfo.TemplateLoc)
1449849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor          << FixItHint::CreateInsertion(LAngleLoc, "<>");
14504d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
14514d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // Create a fake template parameter list that contains only
14524d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // "template<>", so that we treat this construct as a class
14534d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // template specialization.
14544d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        FakedParamLists.push_back(
14551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          Actions.ActOnTemplateParameterList(0, SourceLocation(),
14564d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateInfo.TemplateLoc,
14571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             LAngleLoc,
14581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             0, 0,
14594d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             LAngleLoc));
14604d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        TemplateParams = &FakedParamLists;
14614d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      }
14624d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
14634d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // Build the class template specialization.
14644d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
146523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK,
1466d023aec8907831a18d3514a95b843a7ee06b6b5eDouglas Gregor                       StartLoc, DS.getModulePrivateSpecLoc(), SS,
14672b5289b6fd7e3d9899868410a498c081c9595662John McCall                       TemplateId->Template,
14681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->TemplateNameLoc,
14691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->LAngleLoc,
147039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       TemplateArgsPtr,
14711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->RAngleLoc,
14727f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                       attrs.getList(),
14735354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer                       MultiTemplateParamsArg(
1474cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                    TemplateParams? &(*TemplateParams)[0] : 0,
1475cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                 TemplateParams? TemplateParams->size() : 0));
14764d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    }
14773f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1478f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall             TUK == Sema::TUK_Declaration) {
14793f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Explicit instantiation of a member of a class template
14803f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // specialization, e.g.,
14813f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
14823f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //   template struct Outer<int>::Inner;
14833f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
14842edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt    ProhibitAttributes(attrs);
14852edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
14863f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    TagOrTempResult
148723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      = Actions.ActOnExplicitInstantiation(getCurScope(),
148845f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                           TemplateInfo.ExternLoc,
14891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TemplateInfo.TemplateLoc,
14901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TagType, StartLoc, SS, Name,
14917f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                           NameLoc, attrs.getList());
14929a34edb710917798aa30263374f624f13b594605John McCall  } else if (TUK == Sema::TUK_Friend &&
14939a34edb710917798aa30263374f624f13b594605John McCall             TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
14942edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt    ProhibitAttributes(attrs);
14952edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
14969a34edb710917798aa30263374f624f13b594605John McCall    TagOrTempResult =
14979a34edb710917798aa30263374f624f13b594605John McCall      Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(),
14989a34edb710917798aa30263374f624f13b594605John McCall                                      TagType, StartLoc, SS,
14997f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                      Name, NameLoc, attrs.getList(),
15005354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer                                      MultiTemplateParamsArg(
15019a34edb710917798aa30263374f624f13b594605John McCall                                    TemplateParams? &(*TemplateParams)[0] : 0,
15029a34edb710917798aa30263374f624f13b594605John McCall                                 TemplateParams? TemplateParams->size() : 0));
15033f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else {
15042edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt    if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition)
15052edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt      ProhibitAttributes(attrs);
15062edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
1507c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    bool IsDependent = false;
1508c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
1509a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    // Don't pass down template parameter lists if this is just a tag
1510a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    // reference.  For example, we don't need the template parameters here:
1511a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    //   template <class T> class A *makeA(T t);
1512a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    MultiTemplateParamsArg TParams;
1513a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    if (TUK != Sema::TUK_Reference && TemplateParams)
1514a25c4080a490ea2bab6f54094dd75b19eae83770John McCall      TParams =
1515a25c4080a490ea2bab6f54094dd75b19eae83770John McCall        MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size());
1516a25c4080a490ea2bab6f54094dd75b19eae83770John McCall
15173f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Declaration or definition of a class type
15189a34edb710917798aa30263374f624f13b594605John McCall    TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc,
15197f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                       SS, Name, NameLoc, attrs.getList(), AS,
1520e761230ae3751b525cadd8066c74ec278ee4ef57Douglas Gregor                                       DS.getModulePrivateSpecLoc(),
1521bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith                                       TParams, Owned, IsDependent,
1522bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith                                       SourceLocation(), false,
1523bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith                                       clang::TypeResult());
1524c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
1525c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // If ActOnTag said the type was dependent, try again with the
1526c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // less common call.
15279a34edb710917798aa30263374f624f13b594605John McCall    if (IsDependent) {
15289a34edb710917798aa30263374f624f13b594605John McCall      assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend);
152923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK,
1530193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                                             SS, Name, StartLoc, NameLoc);
15319a34edb710917798aa30263374f624f13b594605John McCall    }
15323f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  }
1533e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1534e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If there is a body, parse it and inform the actions module.
1535f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  if (TUK == Sema::TUK_Definition) {
1536bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    assert(Tok.is(tok::l_brace) ||
15374e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie           (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
15384e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith           isCXX11FinalKeyword());
15394e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().CPlusPlus)
154007fc1ba7553f2f5bf26984091197311decd9028eMichael Han      ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs, TagType,
154107fc1ba7553f2f5bf26984091197311decd9028eMichael Han                                  TagOrTempResult.get());
154207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    else
1543212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
1544e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1545e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1546b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  const char *PrevSpec = 0;
1547b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  unsigned DiagID;
1548b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  bool Result;
1549c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  if (!TypeResult.isInvalid()) {
15500daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara    Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
15510daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                NameLoc.isValid() ? NameLoc : StartLoc,
1552b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                PrevSpec, DiagID, TypeResult.get());
1553c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else if (!TagOrTempResult.isInvalid()) {
15540daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara    Result = DS.SetTypeSpecType(TagType, StartLoc,
15550daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                NameLoc.isValid() ? NameLoc : StartLoc,
15560daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                PrevSpec, DiagID, TagOrTempResult.get(), Owned);
1557c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else {
1558ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    DS.SetTypeSpecError();
155966e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson    return;
156066e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson  }
15611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1562b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  if (Result)
1563fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
1564193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
15654ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // At this point, we've successfully parsed a class-specifier in 'definition'
15664ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // form (e.g. "struct foo { int x; }".  While we could just return here, we're
15674ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // going to look at what comes after it to improve error recovery.  If an
15684ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // impossible token occurs next, we assume that the programmer forgot a ; at
15694ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // the end of the declaration and recover that way.
15704ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  //
1571c9f351700721150a985f21844fbfec55b04e861dRichard Smith  // Also enforce C++ [temp]p3:
1572c9f351700721150a985f21844fbfec55b04e861dRichard Smith  //   In a template-declaration which defines a class, no declarator
1573c9f351700721150a985f21844fbfec55b04e861dRichard Smith  //   is permitted.
157417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos  if (TUK == Sema::TUK_Definition &&
157517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos      (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) {
15767d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis    if (Tok.isNot(tok::semi)) {
15777d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
15787d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis        DeclSpec::getSpecifierName(TagType));
15797d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis      // Push this token back into the preprocessor and change our current token
15807d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis      // to ';' so that the rest of the code recovers as though there were an
15817d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis      // ';' after the definition.
15827d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis      PP.EnterToken(Tok);
15837d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis      Tok.setKind(tok::semi);
15847d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis    }
15854ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  }
1586e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1587e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
15881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
1589e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1590e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-clause : [C++ class.derived]
1591e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ':' base-specifier-list
1592e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier-list:
1593e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier '...'[opt]
1594e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier-list ',' base-specifier '...'[opt]
1595d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseBaseClause(Decl *ClassDecl) {
1596e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  assert(Tok.is(tok::colon) && "Not a base clause");
1597e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  ConsumeToken();
1598e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1599f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Build up an array of parsed base specifiers.
16005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<CXXBaseSpecifier *, 8> BaseInfo;
1601f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
1602e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  while (true) {
1603e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Parse a base-specifier.
1604f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    BaseResult Result = ParseBaseSpecifier(ClassDecl);
16055ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor    if (Result.isInvalid()) {
1606e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Skip the rest of this base specifier, up until the comma or
1607e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // opening brace.
1608f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      SkipUntil(tok::comma, tok::l_brace, true, true);
1609f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    } else {
1610f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      // Add this to our array of base specifiers.
16115ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor      BaseInfo.push_back(Result.get());
1612e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
1613e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1614e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // If the next token is a comma, consume it and keep reading
1615e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // base-specifiers.
1616e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (Tok.isNot(tok::comma)) break;
16171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1618e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Consume the comma.
1619e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
1620e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1621f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
1622f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Attach the base specifiers
1623beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad  Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size());
1624e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1625e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1626e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
1627e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example:
1628e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///    class foo : public bar, virtual private baz {
1629e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers.
1630e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1631e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier: [C++ class.derived]
1632053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///         attribute-specifier-seq[opt] base-type-specifier
1633053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///         attribute-specifier-seq[opt] 'virtual' access-specifier[opt]
1634053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///                 base-type-specifier
1635053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///         attribute-specifier-seq[opt] access-specifier 'virtual'[opt]
1636053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///                 base-type-specifier
1637d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {
1638e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  bool IsVirtual = false;
1639e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation StartLoc = Tok.getLocation();
1640e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1641053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith  ParsedAttributesWithRange Attributes(AttrFactory);
1642053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith  MaybeParseCXX11Attributes(Attributes);
1643053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith
1644e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword.
1645e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
1646e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
1647e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
1648e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1649e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1650053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith  CheckMisplacedCXX11Attribute(Attributes, StartLoc);
1651053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith
1652e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse an (optional) access specifier.
1653e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  AccessSpecifier Access = getAccessSpecifierIfPresent();
165492f883177b162928a8e632e4e3b93fafd2b26072John McCall  if (Access != AS_none)
1655e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
16561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1657053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith  CheckMisplacedCXX11Attribute(Attributes, StartLoc);
1658053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith
1659e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword (again!), in case it came after the
1660e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // access specifier.
1661e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
1662e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SourceLocation VirtualLoc = ConsumeToken();
1663e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (IsVirtual) {
1664e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Complain about duplicate 'virtual'
16651ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner      Diag(VirtualLoc, diag::err_dup_virtual)
1666849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor        << FixItHint::CreateRemoval(VirtualLoc);
1667e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
1668e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1669e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
1670e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1671e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1672053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith  CheckMisplacedCXX11Attribute(Attributes, StartLoc);
1673053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith
167442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Parse the class-name.
16757f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceLocation EndLocation;
167622216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie  SourceLocation BaseLoc;
167722216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie  TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation);
167831a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor  if (BaseType.isInvalid())
167942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor    return true;
16801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1681f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // Parse the optional ellipsis (for a pack expansion). The ellipsis is
1682f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // actually part of the base-specifier-list grammar productions, but we
1683f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // parse it here for convenience.
1684f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  SourceLocation EllipsisLoc;
1685f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  if (Tok.is(tok::ellipsis))
1686f90b27ad077c3339b62befc892382845339f9490Douglas Gregor    EllipsisLoc = ConsumeToken();
1687f90b27ad077c3339b62befc892382845339f9490Douglas Gregor
16881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Find the complete source range for the base-specifier.
16897f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceRange Range(StartLoc, EndLocation);
16901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1691e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Notify semantic analysis that we have parsed a complete
1692e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // base-specifier.
1693053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith  return Actions.ActOnBaseSpecifier(ClassDecl, Range, Attributes, IsVirtual,
1694053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith                                    Access, BaseType.get(), BaseLoc,
1695053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith                                    EllipsisLoc);
1696e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1697e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1698e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is
1699e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier.
1700e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1701e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       access-specifier: [C++ class.derived]
1702e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'private'
1703e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'protected'
1704e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'public'
17051eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAccessSpecifier Parser::getAccessSpecifierIfPresent() const {
1706e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  switch (Tok.getKind()) {
1707e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  default: return AS_none;
1708e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_private: return AS_private;
1709e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_protected: return AS_protected;
1710e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_public: return AS_public;
1711e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1712e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
17134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
171474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor/// \brief If the given declarator has any parts for which parsing has to be
1715a058fd4f0a944174295f77169b438510dad389f8Richard Smith/// delayed, e.g., default arguments, create a late-parsed method declaration
1716a058fd4f0a944174295f77169b438510dad389f8Richard Smith/// record to handle the parsing at the end of the class definition.
171774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregorvoid Parser::HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
171874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                                            Decl *ThisDecl) {
1719d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // We just declared a member function. If this member function
1720a058fd4f0a944174295f77169b438510dad389f8Richard Smith  // has any default arguments, we'll need to parse them later.
1721d33133cdc1af466f9c276249b2621be03867888bEli Friedman  LateParsedMethodDeclaration *LateMethod = 0;
17221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  DeclaratorChunk::FunctionTypeInfo &FTI
1723075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara    = DeclaratorInfo.getFunctionTypeInfo();
172474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
1725d33133cdc1af466f9c276249b2621be03867888bEli Friedman  for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
1726d33133cdc1af466f9c276249b2621be03867888bEli Friedman    if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
1727d33133cdc1af466f9c276249b2621be03867888bEli Friedman      if (!LateMethod) {
1728d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Push this method onto the stack of late-parsed method
1729d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // declarations.
1730d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
1731d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
173223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        LateMethod->TemplateScope = getCurScope()->isTemplateParamScope();
1733d33133cdc1af466f9c276249b2621be03867888bEli Friedman
1734d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Add all of the parameters prior to this one (they don't
1735d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // have default arguments).
1736d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateMethod->DefaultArgs.reserve(FTI.NumArgs);
1737d33133cdc1af466f9c276249b2621be03867888bEli Friedman        for (unsigned I = 0; I < ParamIdx; ++I)
1738d33133cdc1af466f9c276249b2621be03867888bEli Friedman          LateMethod->DefaultArgs.push_back(
17398f8210c47797f013e0fb24a26f9c4751b10783feDouglas Gregor                             LateParsedDefaultArgument(FTI.ArgInfo[I].Param));
1740d33133cdc1af466f9c276249b2621be03867888bEli Friedman      }
1741d33133cdc1af466f9c276249b2621be03867888bEli Friedman
174274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      // Add this parameter to the list of parameters (it may or may
1743d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // not have a default argument).
1744d33133cdc1af466f9c276249b2621be03867888bEli Friedman      LateMethod->DefaultArgs.push_back(
1745d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
1746d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                  FTI.ArgInfo[ParamIdx].DefaultArgTokens));
1747d33133cdc1af466f9c276249b2621be03867888bEli Friedman    }
1748d33133cdc1af466f9c276249b2621be03867888bEli Friedman  }
1749d33133cdc1af466f9c276249b2621be03867888bEli Friedman}
1750d33133cdc1af466f9c276249b2621be03867888bEli Friedman
17514e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith/// isCXX11VirtSpecifier - Determine whether the given token is a C++11
17521f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier.
17531f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
17541f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier:
17551f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         override
17561f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         final
17574e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard SmithVirtSpecifiers::Specifier Parser::isCXX11VirtSpecifier(const Token &Tok) const {
17584e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!getLangOpts().CPlusPlus)
1759cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson    return VirtSpecifiers::VS_None;
1760cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
1761b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  if (Tok.is(tok::identifier)) {
1762b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    IdentifierInfo *II = Tok.getIdentifierInfo();
17631f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
17647eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    // Initialize the contextual keywords.
17657eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    if (!Ident_final) {
17667eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson      Ident_final = &PP.getIdentifierTable().get("final");
17677eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson      Ident_override = &PP.getIdentifierTable().get("override");
17687eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    }
17697eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson
1770b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (II == Ident_override)
1771b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return VirtSpecifiers::VS_Override;
17721f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
1773b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (II == Ident_final)
1774b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return VirtSpecifiers::VS_Final;
1775b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  }
1776b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
1777b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  return VirtSpecifiers::VS_None;
17781f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson}
17791f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
17804e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith/// ParseOptionalCXX11VirtSpecifierSeq - Parse a virt-specifier-seq.
17811f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
17821f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier-seq:
17831f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier
17841f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier-seq virt-specifier
17854e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smithvoid Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS,
1786e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall                                                bool IsInterface) {
1787b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  while (true) {
17884e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith    VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier();
1789b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (Specifier == VirtSpecifiers::VS_None)
1790b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return;
1791b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
1792b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    // C++ [class.mem]p8:
1793b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    //   A virt-specifier-seq shall contain at most one of each virt-specifier.
1794cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson    const char *PrevSpec = 0;
179546127a96b6dd6b93aa18d5f7a55bc2db8b52a2c9Anders Carlsson    if (VS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec))
1796b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier)
1797b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson        << PrevSpec
1798b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson        << FixItHint::CreateRemoval(Tok.getLocation());
1799b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
1800e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall    if (IsInterface && Specifier == VirtSpecifiers::VS_Final) {
1801e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall      Diag(Tok.getLocation(), diag::err_override_control_interface)
1802e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        << VirtSpecifiers::getSpecifierName(Specifier);
1803e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall    } else {
180480ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith      Diag(Tok.getLocation(), getLangOpts().CPlusPlus11 ?
1805e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall           diag::warn_cxx98_compat_override_control_keyword :
1806e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall           diag::ext_override_control_keyword)
1807e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        << VirtSpecifiers::getSpecifierName(Specifier);
1808e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall    }
1809b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    ConsumeToken();
1810b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  }
18111f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson}
18121f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
18134e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith/// isCXX11FinalKeyword - Determine whether the next token is a C++11
18148a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson/// contextual 'final' keyword.
18154e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smithbool Parser::isCXX11FinalKeyword() const {
18164e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!getLangOpts().CPlusPlus)
18178a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    return false;
1818cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
18198a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  if (!Tok.is(tok::identifier))
18208a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    return false;
1821cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
18228a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  // Initialize the contextual keywords.
18238a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  if (!Ident_final) {
18248a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    Ident_final = &PP.getIdentifierTable().get("final");
18258a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    Ident_override = &PP.getIdentifierTable().get("override");
1826cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson  }
18278a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson
18288a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  return Tok.getIdentifierInfo() == Ident_final;
1829cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson}
1830cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
18314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
18324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
18334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declaration:
18344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         decl-specifier-seq[opt] member-declarator-list[opt] ';'
18354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         function-definition ';'[opt]
18364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
18374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         using-declaration                                            [TODO]
1838511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration
18395aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson///         template-declaration
1840bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU]   '__extension__' member-declaration
18414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
18424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator-list:
18434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator
18444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator-list ',' member-declarator
18454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
18464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator:
18471f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         declarator virt-specifier-seq[opt] pure-specifier[opt]
18484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         declarator constant-initializer[opt]
18497a614d8380297fcd2bc23986241905d97222948cRichard Smith/// [C++11] declarator brace-or-equal-initializer[opt]
18504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         identifier[opt] ':' constant-expression
18514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
18521f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier-seq:
18531f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier
18541f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier-seq virt-specifier
18551f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
18561f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier:
18571f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         override
18581f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         final
18591f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
1860e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl///       pure-specifier:
18614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '= 0'
18624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
18634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       constant-initializer:
18644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '=' constant-expression
18654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
186637b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregorvoid Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
18675f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                            AttributeList *AccessAttrs,
1868c9068d7dd94d439cec66c421115d15303e481025John McCall                                       const ParsedTemplateInfo &TemplateInfo,
1869c9068d7dd94d439cec66c421115d15303e481025John McCall                                       ParsingDeclRAIIObject *TemplateDiags) {
18708a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor  if (Tok.is(tok::at)) {
18714e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().ObjC1 && NextToken().isObjCAtKeyword(tok::objc_defs))
18728a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor      Diag(Tok, diag::err_at_defs_cxx);
18738a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    else
18748a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor      Diag(Tok, diag::err_at_in_class);
18758a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor
18768a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    ConsumeToken();
18778a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    SkipUntil(tok::r_brace);
18788a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    return;
18798a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor  }
18808a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor
188160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  // Access declarations.
188283a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith  bool MalformedTypeSpec = false;
188360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  if (!TemplateInfo.Kind &&
188483a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith      (Tok.is(tok::identifier) || Tok.is(tok::coloncolon))) {
188583a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith    if (TryAnnotateCXXScopeToken())
188683a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith      MalformedTypeSpec = true;
188783a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith
188883a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith    bool isAccessDecl;
188983a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith    if (Tok.isNot(tok::annot_cxxscope))
189083a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith      isAccessDecl = false;
189183a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith    else if (NextToken().is(tok::identifier))
189260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      isAccessDecl = GetLookAheadToken(2).is(tok::semi);
189360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    else
189460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      isAccessDecl = NextToken().is(tok::kw_operator);
189560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
189660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    if (isAccessDecl) {
189760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // Collect the scope specifier token we annotated earlier.
189860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      CXXScopeSpec SS;
1899efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor      ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
1900efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor                                     /*EnteringContext=*/false);
190160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
190260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // Try to parse an unqualified-id.
1903e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara      SourceLocation TemplateKWLoc;
190460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      UnqualifiedId Name;
1905e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara      if (ParseUnqualifiedId(SS, false, true, true, ParsedType(),
1906e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                             TemplateKWLoc, Name)) {
190760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        SkipUntil(tok::semi);
190860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        return;
190960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      }
191060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
191160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // TODO: recover from mistakenly-qualified operator declarations.
191260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      if (ExpectAndConsume(tok::semi,
191360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           diag::err_expected_semi_after,
191460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           "access declaration",
191560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           tok::semi))
191660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        return;
191760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
191823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.ActOnUsingDeclaration(getCurScope(), AS,
191960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    false, SourceLocation(),
192060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    SS, Name,
192160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    /* AttrList */ 0,
192260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    /* IsTypeName */ false,
192360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    SourceLocation());
192460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      return;
192560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    }
192660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  }
192760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
1928511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  // static_assert-declaration
1929c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne  if (Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) {
193037b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    // FIXME: Check for templates
193197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
193297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    ParseStaticAssertDeclaration(DeclEnd);
1933682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1934682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
19351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1936682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  if (Tok.is(tok::kw_template)) {
19371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(!TemplateInfo.TemplateParams &&
193837b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor           "Nested template improperly parsed?");
193997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
19401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd,
19415f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                         AS, AccessAttrs);
1942682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1943682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
19445aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson
1945bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  // Handle:  member-declaration ::= '__extension__' member-declaration
1946bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  if (Tok.is(tok::kw___extension__)) {
1947bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    // __extension__ silences extension warnings in the subexpression.
1948bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
1949bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ConsumeToken();
19505f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    return ParseCXXClassMemberDeclaration(AS, AccessAttrs,
19515f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                          TemplateInfo, TemplateDiags);
1952bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  }
19539cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
19544ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it
19554ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // is a bitfield.
1956a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner  ColonProtectionRAIIObject X(*this);
1957193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
19580b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributesWithRange attrs(AttrFactory);
195952b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han  ParsedAttributesWithRange FnAttrs(AttrFactory);
19604e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith  // Optional C++11 attribute-specifier
19614e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith  MaybeParseCXX11Attributes(attrs);
196252b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han  // We need to keep these attributes for future diagnostic
196352b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han  // before they are taken over by declaration specifier.
196452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han  FnAttrs.addAll(attrs.getList());
196552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han  FnAttrs.Range = attrs.Range;
196652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han
19677f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseMicrosoftAttributes(attrs);
1968bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
19699cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_using)) {
19707f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ProhibitAttributes(attrs);
19711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19729cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    // Eat 'using'.
19739cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SourceLocation UsingLoc = ConsumeToken();
19749cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
19759cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    if (Tok.is(tok::kw_namespace)) {
19769cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      Diag(UsingLoc, diag::err_using_namespace_in_class);
19779cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SkipUntil(tok::semi, true, true);
1978ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    } else {
19799cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SourceLocation DeclEnd;
19803e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      // Otherwise, it must be a using-declaration or an alias-declaration.
198178b810559d89e996e00684335407443936ce34a1John McCall      ParseUsingDeclaration(Declarator::MemberContext, TemplateInfo,
198278b810559d89e996e00684335407443936ce34a1John McCall                            UsingLoc, DeclEnd, AS);
19839cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    }
19849cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return;
19859cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
19869cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
19872287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  // Hold late-parsed attributes so we can attach a Decl to them later.
19882287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  LateParsedAttrList CommonLateParsedAttrs;
19892287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
19904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // decl-specifier-seq:
19914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Parse the common declaration-specifiers piece.
1992c9068d7dd94d439cec66c421115d15303e481025John McCall  ParsingDeclSpec DS(*this, TemplateDiags);
19937f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  DS.takeAttributesFrom(attrs);
199483a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith  if (MalformedTypeSpec)
199583a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith    DS.SetTypeSpecError();
19962287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class,
19972287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins                             &CommonLateParsedAttrs);
19984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
19995354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer  MultiTemplateParamsArg TemplateParams(
2000dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
2001dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
2002dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
20034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::semi)) {
20044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
200552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han
200652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han    if (DS.isFriendSpecified())
200752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      ProhibitAttributes(FnAttrs);
200852b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han
2009d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decl *TheDecl =
20100f4be74ff0273e505d383f89174ef539828424edChandler Carruth      Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS, TemplateParams);
2011c9068d7dd94d439cec66c421115d15303e481025John McCall    DS.complete(TheDecl);
201267d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    return;
20134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
201407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
201554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext);
20164867347e82648d3baf09524b98b09c297a5a198fNico Weber  VirtSpecifiers VS;
20174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
2018eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  // Hold late-parsed attributes so we can attach a Decl to them later.
2019eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  LateParsedAttrList LateParsedAttrs;
2020eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
2021a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor  SourceLocation EqualLoc;
2022a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor  bool HasInitializer = false;
2023a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor  ExprResult Init;
20243a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis  if (Tok.isNot(tok::colon)) {
2025a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner    // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
2026a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner    ColonProtectionRAIIObject X(*this);
2027a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner
20283a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Parse the first declarator.
20293a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    ParseDeclarator(DeclaratorInfo);
2030a058fd4f0a944174295f77169b438510dad389f8Richard Smith    // Error parsing the declarator?
203110bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor    if (!DeclaratorInfo.hasName()) {
20323a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      // If so, skip until the semi-colon or a }.
2033d941fa4ff0d0d64b5a541dbd4f99693bff7f6e8dSebastian Redl      SkipUntil(tok::r_brace, true, true);
20343a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (Tok.is(tok::semi))
20353a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeToken();
2036682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
20374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
20384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
20394e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith    ParseOptionalCXX11VirtSpecifierSeq(VS, getCurrentClass().IsInterface);
20404867347e82648d3baf09524b98b09c297a5a198fNico Weber
20411b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson    // If attributes exist after the declarator, but before an '{', parse them.
2042eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
20431b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson
20446a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    // MSVC permits pure specifier on inline functions declared at class scope.
20456a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    // Hence check for =0 before checking for function definition.
20464e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().MicrosoftExt && Tok.is(tok::equal) &&
20476a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        DeclaratorInfo.isFunctionDeclarator() &&
20486a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        NextToken().is(tok::numeric_constant)) {
2049a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor      EqualLoc = ConsumeToken();
20506a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet      Init = ParseInitializer();
20516a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet      if (Init.isInvalid())
20526a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        SkipUntil(tok::comma, true, true);
2053a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor      else
2054a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor        HasInitializer = true;
20556a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    }
20566a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet
205745fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor    FunctionDefinitionKind DefinitionKind = FDK_Declaration;
20583a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // function-definition:
20597a614d8380297fcd2bc23986241905d97222948cRichard Smith    //
20607a614d8380297fcd2bc23986241905d97222948cRichard Smith    // In C++11, a non-function declarator followed by an open brace is a
20617a614d8380297fcd2bc23986241905d97222948cRichard Smith    // braced-init-list for an in-class member initialization, not an
20627a614d8380297fcd2bc23986241905d97222948cRichard Smith    // erroneous function definition.
206380ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith    if (Tok.is(tok::l_brace) && !getLangOpts().CPlusPlus11) {
206445fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor      DefinitionKind = FDK_Definition;
2065e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    } else if (DeclaratorInfo.isFunctionDeclarator()) {
20667a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
206745fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor        DefinitionKind = FDK_Definition;
2068e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      } else if (Tok.is(tok::equal)) {
2069e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        const Token &KW = NextToken();
207045fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor        if (KW.is(tok::kw_default))
207145fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor          DefinitionKind = FDK_Defaulted;
207245fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor        else if (KW.is(tok::kw_delete))
207345fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor          DefinitionKind = FDK_Deleted;
2074e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      }
2075e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    }
2076e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
207752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han    // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains
207852b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han    // to a friend declaration, that declaration shall be a definition.
207952b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han    if (DeclaratorInfo.isFunctionDeclarator() &&
208052b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han        DefinitionKind != FDK_Definition && DS.isFriendSpecified()) {
208152b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      // Diagnose attributes that appear before decl specifier:
208252b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      // [[]] friend int foo();
208352b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      ProhibitAttributes(FnAttrs);
208452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han    }
208552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han
208645fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor    if (DefinitionKind) {
20873a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (!DeclaratorInfo.isFunctionDeclarator()) {
208865ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu        Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params);
20893a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
209065ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu        SkipUntil(tok::r_brace, /*StopAtSemi*/false);
209152b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han
20929ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        // Consume the optional ';'
20939ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        if (Tok.is(tok::semi))
20949ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor          ConsumeToken();
2095682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
20963a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
20973a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis
20983a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
209965ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu        Diag(DeclaratorInfo.getIdentifierLoc(),
210065ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu             diag::err_function_declared_typedef);
21019ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor
21026f9a445760992a6fbff2c0b08becf35ae9eafa71Richard Smith        // Recover by treating the 'typedef' as spurious.
21036f9a445760992a6fbff2c0b08becf35ae9eafa71Richard Smith        DS.ClearStorageClassSpecs();
21043a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
21054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
2106eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      Decl *FunDecl =
21075f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen        ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo, TemplateInfo,
210845fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor                                VS, DefinitionKind, Init);
2109eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
21102287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
21112287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins        CommonLateParsedAttrs[i]->addDecl(FunDecl);
21122287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      }
2113eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
21142287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins        LateParsedAttrs[i]->addDecl(FunDecl);
2115eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      }
2116eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      LateParsedAttrs.clear();
2117e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
2118e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      // Consume the ';' - it's optional unless we have a delete or default
21194b0e6f1da341510c1ad83eaf4c836f3134d0156aRichard Trieu      if (Tok.is(tok::semi))
2120eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith        ConsumeExtraSemi(AfterMemberFunctionDefinition);
21219ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor
2122682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
21233a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    }
21244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
21254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
21264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // member-declarator-list:
21274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator
21284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator-list ',' member-declarator
21294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
21305f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Decl *, 8> DeclsInGroup;
213160d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult BitfieldSize;
21321c94c16317c1a35c1549e022958188eea2567089Richard Smith  bool ExpectSemi = true;
21334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
21344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  while (1) {
21354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // member-declarator:
21364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   declarator pure-specifier[opt]
21377a614d8380297fcd2bc23986241905d97222948cRichard Smith    //   declarator brace-or-equal-initializer[opt]
21384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   identifier[opt] ':' constant-expression
21394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::colon)) {
21404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
21410e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      BitfieldSize = ParseConstantExpression();
21420e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      if (BitfieldSize.isInvalid())
21434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        SkipUntil(tok::comma, true, true);
21444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
21451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2146e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    // If a simple-asm-expr is present, parse it.
2147e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    if (Tok.is(tok::kw_asm)) {
2148e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      SourceLocation Loc;
214960d7b3a319d84d688752be3870615ac0f111fb16John McCall      ExprResult AsmLabel(ParseSimpleAsm(&Loc));
2150e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      if (AsmLabel.isInvalid())
2151e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner        SkipUntil(tok::comma, true, true);
2152e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner
2153e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      DeclaratorInfo.setAsmLabel(AsmLabel.release());
2154e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      DeclaratorInfo.SetRangeEnd(Loc);
2155e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    }
2156e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner
21574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If attributes exist after the declarator, parse them.
2158eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
21594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
21607a614d8380297fcd2bc23986241905d97222948cRichard Smith    // FIXME: When g++ adds support for this, we'll need to check whether it
21617a614d8380297fcd2bc23986241905d97222948cRichard Smith    // goes before or after the GNU attributes and __asm__.
21624e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith    ParseOptionalCXX11VirtSpecifierSeq(VS, getCurrentClass().IsInterface);
21637a614d8380297fcd2bc23986241905d97222948cRichard Smith
2164ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith    InClassInitStyle HasInClassInit = ICIS_NoInit;
2165a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor    if ((Tok.is(tok::equal) || Tok.is(tok::l_brace)) && !HasInitializer) {
21667a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (BitfieldSize.get()) {
21677a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(Tok, diag::err_bitfield_member_init);
21687a614d8380297fcd2bc23986241905d97222948cRichard Smith        SkipUntil(tok::comma, true, true);
21697a614d8380297fcd2bc23986241905d97222948cRichard Smith      } else {
2170147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor        HasInitializer = true;
2171ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith        if (!DeclaratorInfo.isDeclarationOfFunction() &&
2172ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith            DeclaratorInfo.getDeclSpec().getStorageClassSpec()
2173ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith              != DeclSpec::SCS_typedef)
2174ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith          HasInClassInit = Tok.is(tok::equal) ? ICIS_CopyInit : ICIS_ListInit;
21757a614d8380297fcd2bc23986241905d97222948cRichard Smith      }
21767a614d8380297fcd2bc23986241905d97222948cRichard Smith    }
21777a614d8380297fcd2bc23986241905d97222948cRichard Smith
217807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // NOTE: If Sema is the Action module and declarator is an instance field,
2179682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    // this call will *not* return the created decl; It will return null.
218007952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // See Sema::ActOnCXXMemberDeclarator for details.
218167d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall
2182fc35cbca942ccdfe43742c1d786ed168517e0a47Rafael Espindola    NamedDecl *ThisDecl = 0;
218367d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    if (DS.isFriendSpecified()) {
218452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains
218552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      // to a friend declaration, that declaration shall be a definition.
218652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      //
218752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      // Diagnose attributes appear after friend member function declarator:
218852b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      // foo [[]] ();
218952b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      SmallVector<SourceRange, 4> Ranges;
219052b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      DeclaratorInfo.getCXX11AttributeRanges(Ranges);
219152b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      if (!Ranges.empty()) {
219252b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han        for (SmallVector<SourceRange, 4>::iterator I = Ranges.begin(),
219352b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han             E = Ranges.end(); I != E; ++I) {
219452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han          Diag((*I).getBegin(), diag::err_attributes_not_allowed)
219552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han            << *I;
219652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han        }
219752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      }
219852b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han
2199bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall      // TODO: handle initializers, bitfields, 'delete'
220023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo,
22013fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer                                                 TemplateParams);
220237b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    } else {
220323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS,
220467d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  DeclaratorInfo,
22053fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer                                                  TemplateParams,
220667d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  BitfieldSize.release(),
2207ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith                                                  VS, HasInClassInit);
22085f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      if (AccessAttrs)
22095f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen        Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs,
22105f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                         false, true);
221137b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    }
2212147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor
2213eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    // Set the Decl for any late parsed attributes
22142287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
22152287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      CommonLateParsedAttrs[i]->addDecl(ThisDecl);
22162287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins    }
2217eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
22182287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins      LateParsedAttrs[i]->addDecl(ThisDecl);
2219eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    }
2220eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    LateParsedAttrs.clear();
2221eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
2222147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    // Handle the initializer.
22231d87fbaeea4a9fbbd73b3a53641f59f1673098e5David Blaikie    if (HasInClassInit != ICIS_NoInit &&
22241d87fbaeea4a9fbbd73b3a53641f59f1673098e5David Blaikie        DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
22251d87fbaeea4a9fbbd73b3a53641f59f1673098e5David Blaikie        DeclSpec::SCS_static) {
2226147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      // The initializer was deferred; parse it and cache the tokens.
222780ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith      Diag(Tok, getLangOpts().CPlusPlus11 ?
22287fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith           diag::warn_cxx98_compat_nonstatic_member_init :
22297fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith           diag::ext_nonstatic_member_init);
22307fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith
22317a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (DeclaratorInfo.isArrayOfUnknownBound()) {
2232ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith        // C++11 [dcl.array]p3: An array bound may also be omitted when the
2233ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith        // declarator is followed by an initializer.
22347a614d8380297fcd2bc23986241905d97222948cRichard Smith        //
22357a614d8380297fcd2bc23986241905d97222948cRichard Smith        // A brace-or-equal-initializer for a member-declarator is not an
22363164c14cadbb09a05ba811602221e9156077cf44David Blaikie        // initializer in the grammar, so this is ill-formed.
22377a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(Tok, diag::err_incomplete_array_member_init);
22387a614d8380297fcd2bc23986241905d97222948cRichard Smith        SkipUntil(tok::comma, true, true);
22393164c14cadbb09a05ba811602221e9156077cf44David Blaikie        if (ThisDecl)
22403164c14cadbb09a05ba811602221e9156077cf44David Blaikie          // Avoid later warnings about a class member of incomplete type.
22413164c14cadbb09a05ba811602221e9156077cf44David Blaikie          ThisDecl->setInvalidDecl();
22427a614d8380297fcd2bc23986241905d97222948cRichard Smith      } else
22437a614d8380297fcd2bc23986241905d97222948cRichard Smith        ParseCXXNonStaticMemberInitializer(ThisDecl);
2244147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    } else if (HasInitializer) {
2245147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      // Normal initializer.
2246a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor      if (!Init.isUsable())
2247552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor        Init = ParseCXXMemberInitializer(ThisDecl,
2248a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor                 DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
2249a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor
2250147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      if (Init.isInvalid())
2251147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor        SkipUntil(tok::comma, true, true);
2252147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      else if (ThisDecl)
225333deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl        Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid(),
2254a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor                                   DS.getTypeSpecType() == DeclSpec::TST_auto);
2255147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static) {
2256147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      // No initializer.
2257147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      Actions.ActOnUninitializedDecl(ThisDecl,
2258147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor                                   DS.getTypeSpecType() == DeclSpec::TST_auto);
22597a614d8380297fcd2bc23986241905d97222948cRichard Smith    }
2260147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor
2261147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    if (ThisDecl) {
2262147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      Actions.FinalizeDeclaration(ThisDecl);
2263147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      DeclsInGroup.push_back(ThisDecl);
2264147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    }
2265147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor
2266e531001b7e44bee5c4ec0be93efbc75adb37a0e3Richard Smith    if (ThisDecl && DeclaratorInfo.isFunctionDeclarator() &&
2267147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor        DeclaratorInfo.getDeclSpec().getStorageClassSpec()
2268147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor          != DeclSpec::SCS_typedef) {
226974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
2270147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    }
2271147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor
2272147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    DeclaratorInfo.complete(ThisDecl);
22737a614d8380297fcd2bc23986241905d97222948cRichard Smith
22744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If we don't have a comma, it is either the end of the list (a ';')
22754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // or an error, bail out.
22764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.isNot(tok::comma))
22774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
22781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Consume the comma.
22801c94c16317c1a35c1549e022958188eea2567089Richard Smith    SourceLocation CommaLoc = ConsumeToken();
22811c94c16317c1a35c1549e022958188eea2567089Richard Smith
22821c94c16317c1a35c1549e022958188eea2567089Richard Smith    if (Tok.isAtStartOfLine() &&
22831c94c16317c1a35c1549e022958188eea2567089Richard Smith        !MightBeDeclarator(Declarator::MemberContext)) {
22841c94c16317c1a35c1549e022958188eea2567089Richard Smith      // This comma was followed by a line-break and something which can't be
22851c94c16317c1a35c1549e022958188eea2567089Richard Smith      // the start of a declarator. The comma was probably a typo for a
22861c94c16317c1a35c1549e022958188eea2567089Richard Smith      // semicolon.
22871c94c16317c1a35c1549e022958188eea2567089Richard Smith      Diag(CommaLoc, diag::err_expected_semi_declaration)
22881c94c16317c1a35c1549e022958188eea2567089Richard Smith        << FixItHint::CreateReplacement(CommaLoc, ";");
22891c94c16317c1a35c1549e022958188eea2567089Richard Smith      ExpectSemi = false;
22901c94c16317c1a35c1549e022958188eea2567089Richard Smith      break;
22911c94c16317c1a35c1549e022958188eea2567089Richard Smith    }
22921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Parse the next declarator.
22944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    DeclaratorInfo.clear();
22954867347e82648d3baf09524b98b09c297a5a198fNico Weber    VS.clear();
2296147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    BitfieldSize = true;
2297a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor    Init = true;
2298a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor    HasInitializer = false;
22997984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith    DeclaratorInfo.setCommaLoc(CommaLoc);
23001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2301ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling    // Attributes are only allowed on the second declarator.
23027f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseGNUAttributes(DeclaratorInfo);
23034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
23043a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    if (Tok.isNot(tok::colon))
23053a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      ParseDeclarator(DeclaratorInfo);
23064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
23074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
23081c94c16317c1a35c1549e022958188eea2567089Richard Smith  if (ExpectSemi &&
23091c94c16317c1a35c1549e022958188eea2567089Richard Smith      ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
2310ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    // Skip to end of block or statement.
2311ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    SkipUntil(tok::r_brace, true, true);
2312ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    // If we stopped at a ';', eat it.
2313ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    if (Tok.is(tok::semi)) ConsumeToken();
2314682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
23154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
23164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
231723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup.data(),
2318ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner                                  DeclsInGroup.size());
23194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
23204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
23217a614d8380297fcd2bc23986241905d97222948cRichard Smith/// ParseCXXMemberInitializer - Parse the brace-or-equal-initializer or
23227a614d8380297fcd2bc23986241905d97222948cRichard Smith/// pure-specifier. Also detect and reject any attempted defaulted/deleted
23237a614d8380297fcd2bc23986241905d97222948cRichard Smith/// function definition. The location of the '=', if any, will be placed in
23247a614d8380297fcd2bc23986241905d97222948cRichard Smith/// EqualLoc.
23257a614d8380297fcd2bc23986241905d97222948cRichard Smith///
23267a614d8380297fcd2bc23986241905d97222948cRichard Smith///   pure-specifier:
23277a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '= 0'
232833deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///
23297a614d8380297fcd2bc23986241905d97222948cRichard Smith///   brace-or-equal-initializer:
23307a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '=' initializer-expression
233133deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///     braced-init-list
233233deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///
23337a614d8380297fcd2bc23986241905d97222948cRichard Smith///   initializer-clause:
23347a614d8380297fcd2bc23986241905d97222948cRichard Smith///     assignment-expression
233533deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///     braced-init-list
233633deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///
23377a614d8380297fcd2bc23986241905d97222948cRichard Smith///   defaulted/deleted function-definition:
23387a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '=' 'default'
23397a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '=' 'delete'
23407a614d8380297fcd2bc23986241905d97222948cRichard Smith///
23417a614d8380297fcd2bc23986241905d97222948cRichard Smith/// Prior to C++0x, the assignment-expression in an initializer-clause must
23427a614d8380297fcd2bc23986241905d97222948cRichard Smith/// be a constant-expression.
2343552e29985a710f4ced62b39d70557501bd31ca9bDouglas GregorExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,
23447a614d8380297fcd2bc23986241905d97222948cRichard Smith                                             SourceLocation &EqualLoc) {
23457a614d8380297fcd2bc23986241905d97222948cRichard Smith  assert((Tok.is(tok::equal) || Tok.is(tok::l_brace))
23467a614d8380297fcd2bc23986241905d97222948cRichard Smith         && "Data member initializer not starting with '=' or '{'");
23477a614d8380297fcd2bc23986241905d97222948cRichard Smith
2348552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor  EnterExpressionEvaluationContext Context(Actions,
2349552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor                                           Sema::PotentiallyEvaluated,
2350552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor                                           D);
23517a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (Tok.is(tok::equal)) {
23527a614d8380297fcd2bc23986241905d97222948cRichard Smith    EqualLoc = ConsumeToken();
23537a614d8380297fcd2bc23986241905d97222948cRichard Smith    if (Tok.is(tok::kw_delete)) {
23547a614d8380297fcd2bc23986241905d97222948cRichard Smith      // In principle, an initializer of '= delete p;' is legal, but it will
23557a614d8380297fcd2bc23986241905d97222948cRichard Smith      // never type-check. It's better to diagnose it as an ill-formed expression
23567a614d8380297fcd2bc23986241905d97222948cRichard Smith      // than as an ill-formed deleted non-function member.
23577a614d8380297fcd2bc23986241905d97222948cRichard Smith      // An initializer of '= delete p, foo' will never be parsed, because
23587a614d8380297fcd2bc23986241905d97222948cRichard Smith      // a top-level comma always ends the initializer expression.
23597a614d8380297fcd2bc23986241905d97222948cRichard Smith      const Token &Next = NextToken();
23607a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (IsFunction || Next.is(tok::semi) || Next.is(tok::comma) ||
23617a614d8380297fcd2bc23986241905d97222948cRichard Smith           Next.is(tok::eof)) {
23627a614d8380297fcd2bc23986241905d97222948cRichard Smith        if (IsFunction)
23637a614d8380297fcd2bc23986241905d97222948cRichard Smith          Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
23647a614d8380297fcd2bc23986241905d97222948cRichard Smith            << 1 /* delete */;
23657a614d8380297fcd2bc23986241905d97222948cRichard Smith        else
23667a614d8380297fcd2bc23986241905d97222948cRichard Smith          Diag(ConsumeToken(), diag::err_deleted_non_function);
23677a614d8380297fcd2bc23986241905d97222948cRichard Smith        return ExprResult();
23687a614d8380297fcd2bc23986241905d97222948cRichard Smith      }
23697a614d8380297fcd2bc23986241905d97222948cRichard Smith    } else if (Tok.is(tok::kw_default)) {
23707a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (IsFunction)
23717a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(Tok, diag::err_default_delete_in_multiple_declaration)
23727a614d8380297fcd2bc23986241905d97222948cRichard Smith          << 0 /* default */;
23737a614d8380297fcd2bc23986241905d97222948cRichard Smith      else
23747a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(ConsumeToken(), diag::err_default_special_members);
23757a614d8380297fcd2bc23986241905d97222948cRichard Smith      return ExprResult();
23767a614d8380297fcd2bc23986241905d97222948cRichard Smith    }
23777a614d8380297fcd2bc23986241905d97222948cRichard Smith
237833deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl  }
237933deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl  return ParseInitializer();
23807a614d8380297fcd2bc23986241905d97222948cRichard Smith}
23817a614d8380297fcd2bc23986241905d97222948cRichard Smith
23824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition.
23834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
23844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-specification:
23854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declaration member-specification[opt]
23864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         access-specifier ':' member-specification[opt]
23874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
238817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matosvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
238907fc1ba7553f2f5bf26984091197311decd9028eMichael Han                                         SourceLocation AttrFixitLoc,
2390053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith                                         ParsedAttributesWithRange &Attrs,
239117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos                                         unsigned TagType, Decl *TagDecl) {
239217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos  assert((TagType == DeclSpec::TST_struct ||
239317d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos         TagType == DeclSpec::TST_interface ||
239417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos         TagType == DeclSpec::TST_union  ||
239517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos         TagType == DeclSpec::TST_class) && "Invalid TagType!");
239617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos
2397f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
2398f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing struct/union/class body");
23991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
240026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  // Determine whether this is a non-nested class. Note that local
240126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  // classes are *not* considered to be nested classes.
240226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  bool NonNestedClass = true;
240326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  if (!ClassStack.empty()) {
240423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    for (const Scope *S = getCurScope(); S; S = S->getParent()) {
240526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      if (S->isClassScope()) {
240626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // We're inside a class scope, so this is a nested class.
240726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        NonNestedClass = false;
2408e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall
2409e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        // The Microsoft extension __interface does not permit nested classes.
2410e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        if (getCurrentClass().IsInterface) {
2411e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall          Diag(RecordLoc, diag::err_invalid_member_in_interface)
2412e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall            << /*ErrorType=*/6
2413e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall            << (isa<NamedDecl>(TagDecl)
2414e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall                  ? cast<NamedDecl>(TagDecl)->getQualifiedNameAsString()
2415e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall                  : "<anonymous>");
2416e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        }
241726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        break;
241826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      }
241926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor
242026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      if ((S->getFlags() & Scope::FnScope)) {
242126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // If we're in a function or function template declared in the
242226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // body of a class, then this is a local class rather than a
242326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // nested class.
242426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        const Scope *Parent = S->getParent();
242526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        if (Parent->isTemplateParamScope())
242626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor          Parent = Parent->getParent();
242726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        if (Parent->isClassScope())
242826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor          break;
242926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      }
243026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor    }
243126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  }
24324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
24334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Enter a scope for the class.
24343218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
24354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
24366569d68745c8213709740337d2be52b031384f58Douglas Gregor  // Note that we are parsing a new (potentially-nested) class definition.
2437e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall  ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass,
2438e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall                                    TagType == DeclSpec::TST_interface);
24396569d68745c8213709740337d2be52b031384f58Douglas Gregor
2440ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  if (TagDecl)
244123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
2442bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
2443b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  SourceLocation FinalLoc;
2444b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson
2445b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  // Parse the optional 'final' keyword.
24464e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) {
24474e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith    assert(isCXX11FinalKeyword() && "not a class definition");
24488b11b5e6ce086fcaa7344bf84cffefcf4b53f9f6Richard Smith    FinalLoc = ConsumeToken();
2449b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson
2450e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall    if (TagType == DeclSpec::TST_interface) {
2451e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall      Diag(FinalLoc, diag::err_override_control_interface)
2452e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        << "final";
2453e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall    } else {
245480ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith      Diag(FinalLoc, getLangOpts().CPlusPlus11 ?
2455e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall           diag::warn_cxx98_compat_override_control_keyword :
2456e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall           diag::ext_override_control_keyword) << "final";
2457e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall    }
24582e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
245907fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // Parse any C++11 attributes after 'final' keyword.
246007fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // These attributes are not allowed to appear here,
246107fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // and the only possible place for them to appertain
246207fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // to the class would be between class-key and class-name.
2463053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith    CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
2464b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  }
2465cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
2466bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  if (Tok.is(tok::colon)) {
2467bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    ParseBaseClause(TagDecl);
2468bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
2469bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    if (!Tok.is(tok::l_brace)) {
2470bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall      Diag(Tok, diag::err_expected_lbrace_after_base_specifiers);
2471db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall
2472db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall      if (TagDecl)
247323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);
2474bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall      return;
2475bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    }
2476bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  }
2477bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
2478bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  assert(Tok.is(tok::l_brace));
24794a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_brace);
24804a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
2481bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
248242a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
24832c3ee54e51d835a35bbf781c69e17f39e2ba0480Anders Carlsson    Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc,
24844a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                            T.getOpenLocation());
2485f9368159334ff86ea5fa367225c1a580977f3b03John McCall
24864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // C++ 11p3: Members of a class defined with the keyword class are private
24874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // by default. Members of a class defined with the keywords struct or union
24884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // are public by default.
24894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  AccessSpecifier CurAS;
24904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (TagType == DeclSpec::TST_class)
24914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_private;
24924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  else
24934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_public;
24945f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  ParsedAttributes AccessAttrs(AttrFactory);
24954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
249607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  if (TagDecl) {
249707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    // While we still have something to read, read the member-declarations.
249807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
249907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Each iteration of this loop reads one member-declaration.
250007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor
25014e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
2502563a645de82231a55e221fe655b7188bf8369662Francois Pichet          Tok.is(tok::kw___if_not_exists))) {
2503563a645de82231a55e221fe655b7188bf8369662Francois Pichet        ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
2504563a645de82231a55e221fe655b7188bf8369662Francois Pichet        continue;
2505563a645de82231a55e221fe655b7188bf8369662Francois Pichet      }
2506563a645de82231a55e221fe655b7188bf8369662Francois Pichet
250707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Check for extraneous top-level semicolon.
250807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      if (Tok.is(tok::semi)) {
2509eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith        ConsumeExtraSemi(InsideStruct, TagType);
251007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        continue;
251107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      }
25121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2513aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman      if (Tok.is(tok::annot_pragma_vis)) {
2514aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman        HandlePragmaVisibility();
2515aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman        continue;
2516aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman      }
2517aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman
2518aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman      if (Tok.is(tok::annot_pragma_pack)) {
2519aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman        HandlePragmaPack();
2520aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman        continue;
2521aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman      }
2522aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman
2523f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis      if (Tok.is(tok::annot_pragma_align)) {
2524f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis        HandlePragmaAlign();
2525f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis        continue;
2526f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis      }
2527f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis
2528c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev      if (Tok.is(tok::annot_pragma_openmp)) {
2529c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev        ParseOpenMPDeclarativeDirective();
2530c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev        continue;
2531c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev      }
2532c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
253307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      AccessSpecifier AS = getAccessSpecifierIfPresent();
253407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      if (AS != AS_none) {
253507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        // Current token is a C++ access specifier.
253607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        CurAS = AS;
253707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        SourceLocation ASLoc = Tok.getLocation();
253813f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        unsigned TokLength = Tok.getLength();
253907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        ConsumeToken();
25405f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen        AccessAttrs.clear();
25415f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen        MaybeParseGNUAttributes(AccessAttrs);
25425f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
254313f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        SourceLocation EndLoc;
254413f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        if (Tok.is(tok::colon)) {
254513f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          EndLoc = Tok.getLocation();
254613f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          ConsumeToken();
254713f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        } else if (Tok.is(tok::semi)) {
254813f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          EndLoc = Tok.getLocation();
254913f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          ConsumeToken();
255013f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          Diag(EndLoc, diag::err_expected_colon)
255113f8daf70637f8f295134ac8e089dd7721e09085David Blaikie            << FixItHint::CreateReplacement(EndLoc, ":");
255213f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        } else {
255313f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          EndLoc = ASLoc.getLocWithOffset(TokLength);
255413f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          Diag(EndLoc, diag::err_expected_colon)
255513f8daf70637f8f295134ac8e089dd7721e09085David Blaikie            << FixItHint::CreateInsertion(EndLoc, ":");
255613f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        }
2557c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen
2558e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        // The Microsoft extension __interface does not permit non-public
2559e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        // access specifiers.
2560e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        if (TagType == DeclSpec::TST_interface && CurAS != AS_public) {
2561e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall          Diag(ASLoc, diag::err_access_specifier_interface)
2562e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall            << (CurAS == AS_protected);
2563e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        }
2564e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall
2565c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen        if (Actions.ActOnAccessSpecifier(AS, ASLoc, EndLoc,
2566c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen                                         AccessAttrs.getList())) {
2567c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen          // found another attribute than only annotations
2568c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen          AccessAttrs.clear();
2569c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen        }
2570c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen
257107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        continue;
257207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      }
25734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
257407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // FIXME: Make sure we don't have a template here.
25754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
257607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Parse all the comma separated declarators.
25775f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      ParseCXXClassMemberDeclaration(CurAS, AccessAttrs.getList());
257807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    }
25791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
25804a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
258107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  } else {
258207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    SkipUntil(tok::r_brace, false, false);
25834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
25841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
25854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // If attributes exist after class contents, parse them.
25860b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
25877f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseGNUAttributes(attrs);
25884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
258942a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
259023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
25914a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                              T.getOpenLocation(),
25924a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                              T.getCloseLocation(),
25937f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                              attrs.getList());
25944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
259574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  // C++11 [class.mem]p2:
259674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  //   Within the class member-specification, the class is regarded as complete
2597a058fd4f0a944174295f77169b438510dad389f8Richard Smith  //   within function bodies, default arguments, and
259874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  //   brace-or-equal-initializers for non-static data members (including such
259974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  //   things in nested classes).
260007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  if (TagDecl && NonNestedClass) {
26014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // We are not inside a nested class. This class and its nested classes
260272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    // are complete and we can parse the delayed portions of method
2603eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    // declarations and the lexed inline method definitions, along with any
2604eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    // delayed attributes.
2605e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor    SourceLocation SavedPrevTokLocation = PrevTokLocation;
2606eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    ParseLexedAttributes(getCurrentClass());
26076569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDeclarations(getCurrentClass());
2608a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith
2609a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith    // We've finished with all pending member declarations.
2610a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith    Actions.ActOnFinishCXXMemberDecls();
2611a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith
26127a614d8380297fcd2bc23986241905d97222948cRichard Smith    ParseLexedMemberInitializers(getCurrentClass());
26136569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDefs(getCurrentClass());
2614e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor    PrevTokLocation = SavedPrevTokLocation;
26154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
26164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
261742a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
26184a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,
26194a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                     T.getCloseLocation());
2620db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall
26214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Leave the class scope.
26226569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingDef.Pop();
26238935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ClassScope.Exit();
26244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
26257ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
26267ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer,
26277ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a
26287ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers
26297ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below:
26307ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
26317ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code
26327ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { };
26337ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base {
26347ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   int x;
26357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   float f;
26367ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public:
26377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   Derived(float f) : Base(), x(17), f(f) { }
26387ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// };
26397ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode
26407ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
26411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  ctor-initializer:
26421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///          ':' mem-initializer-list
26437ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
26441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  mem-initializer-list:
26453fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor///          mem-initializer ...[opt]
26463fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor///          mem-initializer ...[opt] , mem-initializer-list
2647d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
26487ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
26497ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
265028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  // Poison the SEH identifiers so they are flagged as illegal in constructor initializers
265128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true);
26527ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation ColonLoc = ConsumeToken();
26531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
26545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<CXXCtorInitializer*, 4> MemInitializers;
26559db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  bool AnyErrors = false;
2656193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
26577ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  do {
26580133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    if (Tok.is(tok::code_completion)) {
26590133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      Actions.CodeCompleteConstructorInitializer(ConstructorDecl,
26600133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor                                                 MemInitializers.data(),
26610133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor                                                 MemInitializers.size());
26627d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return cutOffParsing();
26630133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    } else {
26640133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
26650133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      if (!MemInit.isInvalid())
26660133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor        MemInitializers.push_back(MemInit.get());
26670133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      else
26680133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor        AnyErrors = true;
26690133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    }
26700133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor
26717ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    if (Tok.is(tok::comma))
26727ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      ConsumeToken();
26737ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    else if (Tok.is(tok::l_brace))
26747ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
2675b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor    // If the next token looks like a base or member initializer, assume that
2676b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor    // we're just missing a comma.
2677751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor    else if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) {
2678751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor      SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
2679751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor      Diag(Loc, diag::err_ctor_init_missing_comma)
2680751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor        << FixItHint::CreateInsertion(Loc, ", ");
2681751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor    } else {
26827ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      // Skip over garbage, until we get to '{'.  Don't eat the '{'.
2683d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl      Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
26847ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      SkipUntil(tok::l_brace, true, true);
26857ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
26867ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    }
26877ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  } while (true);
26887ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
268993c8617bec98aeb769ee9f569d7ed439eec03249David Blaikie  Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, MemInitializers,
26909db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                               AnyErrors);
26917ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
26927ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
26937ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is
26947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one
26957ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See
26967ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example.
26977ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
26987ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer:
26997ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         mem-initializer-id '(' expression-list[opt] ')'
2700dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// [C++0x] mem-initializer-id braced-init-list
27011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
27027ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id:
27037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         '::'[opt] nested-name-specifier[opt] class-name
27047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         identifier
2705d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
2706bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  // parse '::'[opt] nested-name-specifier[opt]
2707bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  CXXScopeSpec SS;
2708efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
2709b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TemplateTypeTy;
2710961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (Tok.is(tok::annot_template_id)) {
271125a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
2712d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor    if (TemplateId->Kind == TNK_Type_template ||
2713d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor        TemplateId->Kind == TNK_Dependent_template_name) {
2714059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
2715961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
2716b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      TemplateTypeTy = getTypeAnnotation(Tok);
2717961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    }
2718961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  }
2719f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  // Uses of decltype will already have been converted to annot_decltype by
2720f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  // ParseOptionalCXXScopeSpecifier at this point.
2721f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  if (!TemplateTypeTy && Tok.isNot(tok::identifier)
2722f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie      && Tok.isNot(tok::annot_decltype)) {
27231ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_member_or_base_name);
27247ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
27257ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
27261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2727f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  IdentifierInfo *II = 0;
2728f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  DeclSpec DS(AttrFactory);
2729f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  SourceLocation IdLoc = Tok.getLocation();
2730f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  if (Tok.is(tok::annot_decltype)) {
2731f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie    // Get the decltype expression, if there is one.
2732f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie    ParseDecltypeSpecifier(DS);
2733f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  } else {
2734f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie    if (Tok.is(tok::identifier))
2735f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie      // Get the identifier. This may be a member name or a class name,
2736f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie      // but we'll let the semantic analysis determine which it is.
2737f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie      II = Tok.getIdentifierInfo();
2738f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie    ConsumeToken();
2739f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  }
2740f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie
27417ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
27427ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Parse the '('.
274380ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith  if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
27447fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith    Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
27457fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith
27466df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    ExprResult InitList = ParseBraceInitializer();
27476df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    if (InitList.isInvalid())
27486df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      return true;
27496df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
27506df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    SourceLocation EllipsisLoc;
27516df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    if (Tok.is(tok::ellipsis))
27526df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      EllipsisLoc = ConsumeToken();
27536df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
27546df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
2755f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie                                       TemplateTypeTy, DS, IdLoc,
2756f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie                                       InitList.take(), EllipsisLoc);
2757dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl  } else if(Tok.is(tok::l_paren)) {
27584a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    BalancedDelimiterTracker T(*this, tok::l_paren);
27594a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeOpen();
2760dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl
2761dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    // Parse the optional expression-list.
27624e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer    ExprVector ArgExprs;
2763dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    CommaLocsTy CommaLocs;
2764dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
2765dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl      SkipUntil(tok::r_paren);
2766dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl      return true;
2767dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    }
27687ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
27694a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
27707ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
2771dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    SourceLocation EllipsisLoc;
2772dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    if (Tok.is(tok::ellipsis))
2773dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl      EllipsisLoc = ConsumeToken();
27747ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
2775dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
2776f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie                                       TemplateTypeTy, DS, IdLoc,
27774e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer                                       T.getOpenLocation(), ArgExprs.data(),
27784a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                       ArgExprs.size(), T.getCloseLocation(),
2779dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl                                       EllipsisLoc);
2780dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl  }
2781dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl
278280ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith  Diag(Tok, getLangOpts().CPlusPlus11 ? diag::err_expected_lparen_or_lbrace
2783dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl                                  : diag::err_expected_lparen);
2784dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl  return true;
27857ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
27860fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
27877acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// \brief Parse a C++ exception-specification if present (C++0x [except.spec]).
27880fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
2789a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       exception-specification:
27907acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         dynamic-exception-specification
27917acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         noexcept-specification
27927acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///
27937acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///       noexcept-specification:
27947acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         'noexcept'
27957acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         'noexcept' '(' constant-expression ')'
27967acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType
2797a058fd4f0a944174295f77169b438510dad389f8Richard SmithParser::tryParseExceptionSpecification(
279874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                    SourceRange &SpecificationRange,
27995f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                    SmallVectorImpl<ParsedType> &DynamicExceptions,
28005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                    SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
2801a058fd4f0a944174295f77169b438510dad389f8Richard Smith                    ExprResult &NoexceptExpr) {
28027acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  ExceptionSpecificationType Result = EST_None;
2803a058fd4f0a944174295f77169b438510dad389f8Richard Smith
28047acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // See if there's a dynamic specification.
28057acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.is(tok::kw_throw)) {
28067acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Result = ParseDynamicExceptionSpecification(SpecificationRange,
28077acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                                DynamicExceptions,
28087acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                                DynamicExceptionRanges);
28097acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    assert(DynamicExceptions.size() == DynamicExceptionRanges.size() &&
28107acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl           "Produced different number of exception types and ranges.");
28117acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
28127acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
28137acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // If there's no noexcept specification, we're done.
28147acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.isNot(tok::kw_noexcept))
28157acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    return Result;
28167acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
2817841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith  Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
2818841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith
28197acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // If we already had a dynamic specification, parse the noexcept for,
28207acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // recovery, but emit a diagnostic and don't store the results.
28217acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SourceRange NoexceptRange;
28227acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  ExceptionSpecificationType NoexceptType = EST_None;
28237acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
28247acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SourceLocation KeywordLoc = ConsumeToken();
28257acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.is(tok::l_paren)) {
28267acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // There is an argument.
28274a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    BalancedDelimiterTracker T(*this, tok::l_paren);
28284a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeOpen();
28297acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptType = EST_ComputedNoexcept;
28307acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptExpr = ParseConstantExpression();
283160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    // The argument must be contextually convertible to bool. We use
283260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    // ActOnBooleanCondition for this purpose.
283360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    if (!NoexceptExpr.isInvalid())
283460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl      NoexceptExpr = Actions.ActOnBooleanCondition(getCurScope(), KeywordLoc,
283560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl                                                   NoexceptExpr.get());
28364a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
28374a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());
28387acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  } else {
28397acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // There is no argument.
28407acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptType = EST_BasicNoexcept;
28417acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptRange = SourceRange(KeywordLoc, KeywordLoc);
28427acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
28437acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
28447acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Result == EST_None) {
28457acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SpecificationRange = NoexceptRange;
28467acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Result = NoexceptType;
28477acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
28487acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // If there's a dynamic specification after a noexcept specification,
28497acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // parse that and ignore the results.
28507acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    if (Tok.is(tok::kw_throw)) {
28517acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
28527acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions,
28537acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                         DynamicExceptionRanges);
28547acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    }
28557acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  } else {
28567acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
28577acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
28587acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
28597acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  return Result;
28607acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl}
28617acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
28627acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// ParseDynamicExceptionSpecification - Parse a C++
28637acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification (C++ [except.spec]).
28647acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///
28657acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///       dynamic-exception-specification:
2866a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         'throw' '(' type-id-list [opt] ')'
2867a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS]    'throw' '(' '...' ')'
28681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
2869a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       type-id-list:
2870a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor///         type-id ... [opt]
2871a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor///         type-id-list ',' type-id ... [opt]
28720fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
28737acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(
28747acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                  SourceRange &SpecificationRange,
28755f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                  SmallVectorImpl<ParsedType> &Exceptions,
28765f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                  SmallVectorImpl<SourceRange> &Ranges) {
28770fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  assert(Tok.is(tok::kw_throw) && "expected throw");
28781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
28797acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SpecificationRange.setBegin(ConsumeToken());
28804a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
28814a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.consumeOpen()) {
28827acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Diag(Tok, diag::err_expected_lparen_after) << "throw";
28837acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SpecificationRange.setEnd(SpecificationRange.getBegin());
288460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    return EST_DynamicNone;
28850fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
28860fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
2887a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // Parse throw(...), a Microsoft extension that means "this function
2888a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // can throw anything".
2889a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  if (Tok.is(tok::ellipsis)) {
2890a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    SourceLocation EllipsisLoc = ConsumeToken();
28914e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (!getLangOpts().MicrosoftExt)
2892a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor      Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
28934a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
28944a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    SpecificationRange.setEnd(T.getCloseLocation());
289560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    return EST_MSAny;
2896a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  }
2897a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor
28980fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  // Parse the sequence of type-ids.
2899ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl  SourceRange Range;
29000fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  while (Tok.isNot(tok::r_paren)) {
2901ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    TypeResult Res(ParseTypeName(&Range));
29027acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
2903a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor    if (Tok.is(tok::ellipsis)) {
2904a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      // C++0x [temp.variadic]p5:
2905a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      //   - In a dynamic-exception-specification (15.4); the pattern is a
2906a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      //     type-id.
2907a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      SourceLocation Ellipsis = ConsumeToken();
29087acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      Range.setEnd(Ellipsis);
2909a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      if (!Res.isInvalid())
2910a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor        Res = Actions.ActOnPackExpansion(Res.get(), Ellipsis);
2911a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor    }
29127acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
2913ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    if (!Res.isInvalid()) {
29147dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl      Exceptions.push_back(Res.get());
2915ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl      Ranges.push_back(Range);
2916ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    }
2917a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor
29180fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor    if (Tok.is(tok::comma))
29190fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      ConsumeToken();
29207dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl    else
29210fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      break;
29220fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
29230fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
29244a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
29254a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  SpecificationRange.setEnd(T.getCloseLocation());
292660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl  return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic;
29270fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor}
29286569d68745c8213709740337d2be52b031384f58Douglas Gregor
2929dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// ParseTrailingReturnType - Parse a trailing return type on a new-style
2930dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// function declaration.
2931ae7902c4293d9de8b9591759513f0d075f45022aDouglas GregorTypeResult Parser::ParseTrailingReturnType(SourceRange &Range) {
2932dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  assert(Tok.is(tok::arrow) && "expected arrow");
2933dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
2934dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  ConsumeToken();
2935dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
29367796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  return ParseTypeName(&Range, Declarator::TrailingReturnContext);
2937dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor}
2938dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
29396569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief We have just started parsing the definition of a new class,
29406569d68745c8213709740337d2be52b031384f58Douglas Gregor/// so push that class onto our stack of classes that is currently
29416569d68745c8213709740337d2be52b031384f58Douglas Gregor/// being parsed.
2942eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallSema::ParsingClassState
2943e402e72273cde2a64fa6097c1fe93f500038675dJohn McCallParser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass,
2944e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall                         bool IsInterface) {
294526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  assert((NonNestedClass || !ClassStack.empty()) &&
29466569d68745c8213709740337d2be52b031384f58Douglas Gregor         "Nested class without outer class");
2947e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall  ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass, IsInterface));
2948eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  return Actions.PushParsingClass();
29496569d68745c8213709740337d2be52b031384f58Douglas Gregor}
29506569d68745c8213709740337d2be52b031384f58Douglas Gregor
29516569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Deallocate the given parsed class and all of its nested
29526569d68745c8213709740337d2be52b031384f58Douglas Gregor/// classes.
29536569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
2954d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I)
2955d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    delete Class->LateParsedDeclarations[I];
29566569d68745c8213709740337d2be52b031384f58Douglas Gregor  delete Class;
29576569d68745c8213709740337d2be52b031384f58Douglas Gregor}
29586569d68745c8213709740337d2be52b031384f58Douglas Gregor
29596569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Pop the top class of the stack of classes that are
29606569d68745c8213709740337d2be52b031384f58Douglas Gregor/// currently being parsed.
29616569d68745c8213709740337d2be52b031384f58Douglas Gregor///
29626569d68745c8213709740337d2be52b031384f58Douglas Gregor/// This routine should be called when we have finished parsing the
29636569d68745c8213709740337d2be52b031384f58Douglas Gregor/// definition of a class, but have not yet popped the Scope
29646569d68745c8213709740337d2be52b031384f58Douglas Gregor/// associated with the class's definition.
2965eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Parser::PopParsingClass(Sema::ParsingClassState state) {
29666569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");
29671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2968eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  Actions.PopParsingClass(state);
2969eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
29706569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingClass *Victim = ClassStack.top();
29716569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.pop();
29726569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (Victim->TopLevelClass) {
29736569d68745c8213709740337d2be52b031384f58Douglas Gregor    // Deallocate all of the nested classes of this class,
29746569d68745c8213709740337d2be52b031384f58Douglas Gregor    // recursively: we don't need to keep any of this information.
29756569d68745c8213709740337d2be52b031384f58Douglas Gregor    DeallocateParsedClasses(Victim);
29766569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
29771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
29786569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Missing top-level class?");
29796569d68745c8213709740337d2be52b031384f58Douglas Gregor
2980d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (Victim->LateParsedDeclarations.empty()) {
29816569d68745c8213709740337d2be52b031384f58Douglas Gregor    // The victim is a nested class, but we will not need to perform
29826569d68745c8213709740337d2be52b031384f58Douglas Gregor    // any processing after the definition of this class since it has
29836569d68745c8213709740337d2be52b031384f58Douglas Gregor    // no members whose handling was delayed. Therefore, we can just
29846569d68745c8213709740337d2be52b031384f58Douglas Gregor    // remove this nested class.
2985d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    DeallocateParsedClasses(Victim);
29866569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
29876569d68745c8213709740337d2be52b031384f58Douglas Gregor  }
29886569d68745c8213709740337d2be52b031384f58Douglas Gregor
29896569d68745c8213709740337d2be52b031384f58Douglas Gregor  // This nested class has some members that will need to be processed
29906569d68745c8213709740337d2be52b031384f58Douglas Gregor  // after the top-level class is completely defined. Therefore, add
29916569d68745c8213709740337d2be52b031384f58Douglas Gregor  // it to the list of nested classes within its parent.
299223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  assert(getCurScope()->isClassScope() && "Nested class outside of class scope?");
2993d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ClassStack.top()->LateParsedDeclarations.push_back(new LateParsedClass(this, Victim));
299423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope();
29956569d68745c8213709740337d2be52b031384f58Douglas Gregor}
2996bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2997c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// \brief Try to parse an 'identifier' which appears within an attribute-token.
2998c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///
2999c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// \return the parsed identifier on success, and 0 if the next token is not an
3000c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute-token.
3001c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///
3002c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// C++11 [dcl.attr.grammar]p3:
3003c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///   If a keyword or an alternative token that satisfies the syntactic
3004c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///   requirements of an identifier is contained in an attribute-token,
3005c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///   it is considered an identifier.
3006c56298d87a9df507805a548d7d515e8b511df2c0Richard SmithIdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(SourceLocation &Loc) {
3007c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  switch (Tok.getKind()) {
3008c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  default:
3009c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    // Identifiers and keywords have identifier info attached.
3010c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
3011c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      Loc = ConsumeToken();
3012c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      return II;
3013c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    }
3014c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    return 0;
3015c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith
3016c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::ampamp:       // 'and'
3017c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::pipe:         // 'bitor'
3018c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::pipepipe:     // 'or'
3019c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::caret:        // 'xor'
3020c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::tilde:        // 'compl'
3021c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::amp:          // 'bitand'
3022c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::ampequal:     // 'and_eq'
3023c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::pipeequal:    // 'or_eq'
3024c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::caretequal:   // 'xor_eq'
3025c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::exclaim:      // 'not'
3026c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::exclaimequal: // 'not_eq'
3027c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    // Alternative tokens do not have identifier info, but their spelling
3028c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    // starts with an alphabetical character.
3029cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    SmallString<8> SpellingBuf;
3030c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    StringRef Spelling = PP.getSpelling(Tok.getLocation(), SpellingBuf);
30313f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose    if (isLetter(Spelling[0])) {
3032c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      Loc = ConsumeToken();
30330eb7526cd2524af78fb9a2a2522045fb25fc3d27Benjamin Kramer      return &PP.getIdentifierTable().get(Spelling);
3034c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    }
3035c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    return 0;
3036c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  }
3037c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith}
3038c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith
30396880f492365cc4fa4c941aa83688635003ee7498Michael Hanstatic bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,
30406880f492365cc4fa4c941aa83688635003ee7498Michael Han                                               IdentifierInfo *ScopeName) {
30416880f492365cc4fa4c941aa83688635003ee7498Michael Han  switch (AttributeList::getKind(AttrName, ScopeName,
30426880f492365cc4fa4c941aa83688635003ee7498Michael Han                                 AttributeList::AS_CXX11)) {
30436880f492365cc4fa4c941aa83688635003ee7498Michael Han  case AttributeList::AT_CarriesDependency:
30446880f492365cc4fa4c941aa83688635003ee7498Michael Han  case AttributeList::AT_FallThrough:
3045cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith  case AttributeList::AT_CXX11NoReturn: {
30466880f492365cc4fa4c941aa83688635003ee7498Michael Han    return true;
30476880f492365cc4fa4c941aa83688635003ee7498Michael Han  }
30486880f492365cc4fa4c941aa83688635003ee7498Michael Han
30496880f492365cc4fa4c941aa83688635003ee7498Michael Han  default:
30506880f492365cc4fa4c941aa83688635003ee7498Michael Han    return false;
30516880f492365cc4fa4c941aa83688635003ee7498Michael Han  }
30526880f492365cc4fa4c941aa83688635003ee7498Michael Han}
30536880f492365cc4fa4c941aa83688635003ee7498Michael Han
3054c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier. Currently
30553497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// only parses standard attributes.
3056bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
30576ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-specifier:
3058bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' '[' attribute-list ']' ']'
305982d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne///         alignment-specifier
3060bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
30616ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-list:
3062bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute[opt]
3063bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-list ',' attribute[opt]
3064c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///         attribute '...'
3065c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///         attribute-list ',' attribute '...'
3066bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
30676ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute:
3068bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-token attribute-argument-clause[opt]
3069bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
30706ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-token:
3071bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
3072bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-scoped-token
3073bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
30746ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-scoped-token:
3075bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-namespace '::' identifier
3076bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
30776ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-namespace:
3078bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
3079bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
30806ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-argument-clause:
3081bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
3082bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
30836ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] balanced-token-seq:
3084bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token
3085bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token-seq balanced-token
3086bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
30876ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] balanced-token:
3088bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
3089bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' balanced-token-seq ']'
3090bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '{' balanced-token-seq '}'
3091bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         any token but '(', ')', '[', ']', '{', or '}'
3092c56298d87a9df507805a548d7d515e8b511df2c0Richard Smithvoid Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
30933497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne                                          SourceLocation *endLoc) {
309482d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne  if (Tok.is(tok::kw_alignas)) {
309541be673e93ed225b45479557b20ff19b3082bae8Richard Smith    Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas);
309682d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne    ParseAlignmentSpecifier(attrs, endLoc);
309782d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne    return;
309882d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne  }
309982d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne
3100bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
31016ee326af4e77e6f05973486097884d7431f2108dRichard Smith      && "Not a C++11 attribute list");
3102bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
310341be673e93ed225b45479557b20ff19b3082bae8Richard Smith  Diag(Tok.getLocation(), diag::warn_cxx98_compat_attribute);
310441be673e93ed225b45479557b20ff19b3082bae8Richard Smith
3105bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
3106bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
3107193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
3108cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith  llvm::SmallDenseMap<IdentifierInfo*, SourceLocation, 4> SeenAttrs;
3109cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith
3110c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  while (Tok.isNot(tok::r_square)) {
3111bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // attribute not present
3112bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::comma)) {
3113bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
3114bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      continue;
3115bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
3116bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
3117c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    SourceLocation ScopeLoc, AttrLoc;
3118c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    IdentifierInfo *ScopeName = 0, *AttrName = 0;
3119c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith
3120c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    AttrName = TryParseCXX11AttributeIdentifier(AttrLoc);
3121c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    if (!AttrName)
3122c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      // Break out to the "expected ']'" diagnostic.
3123c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      break;
3124193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
3125bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // scoped attribute
3126bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::coloncolon)) {
3127bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
3128bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
3129c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      ScopeName = AttrName;
3130c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      ScopeLoc = AttrLoc;
3131c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith
3132c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      AttrName = TryParseCXX11AttributeIdentifier(AttrLoc);
3133c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      if (!AttrName) {
3134bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        Diag(Tok.getLocation(), diag::err_expected_ident);
3135bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        SkipUntil(tok::r_square, tok::comma, true, true);
3136bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        continue;
3137bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
3138bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
3139bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
31406880f492365cc4fa4c941aa83688635003ee7498Michael Han    bool StandardAttr = IsBuiltInOrStandardCXX11Attribute(AttrName,ScopeName);
3141bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    bool AttrParsed = false;
31426880f492365cc4fa4c941aa83688635003ee7498Michael Han
3143cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith    if (StandardAttr &&
3144cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith        !SeenAttrs.insert(std::make_pair(AttrName, AttrLoc)).second)
3145cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith      Diag(AttrLoc, diag::err_cxx11_attribute_repeated)
3146cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith        << AttrName << SourceRange(SeenAttrs[AttrName]);
3147cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith
31486880f492365cc4fa4c941aa83688635003ee7498Michael Han    // Parse attribute arguments
31496880f492365cc4fa4c941aa83688635003ee7498Michael Han    if (Tok.is(tok::l_paren)) {
31506880f492365cc4fa4c941aa83688635003ee7498Michael Han      if (ScopeName && ScopeName->getName() == "gnu") {
31516880f492365cc4fa4c941aa83688635003ee7498Michael Han        ParseGNUAttributeArgs(AttrName, AttrLoc, attrs, endLoc,
31526880f492365cc4fa4c941aa83688635003ee7498Michael Han                              ScopeName, ScopeLoc, AttributeList::AS_CXX11);
31536880f492365cc4fa4c941aa83688635003ee7498Michael Han        AttrParsed = true;
31546880f492365cc4fa4c941aa83688635003ee7498Michael Han      } else {
31556880f492365cc4fa4c941aa83688635003ee7498Michael Han        if (StandardAttr)
31566880f492365cc4fa4c941aa83688635003ee7498Michael Han          Diag(Tok.getLocation(), diag::err_cxx11_attribute_forbids_arguments)
31576880f492365cc4fa4c941aa83688635003ee7498Michael Han            << AttrName->getName();
31586880f492365cc4fa4c941aa83688635003ee7498Michael Han
31596880f492365cc4fa4c941aa83688635003ee7498Michael Han        // FIXME: handle other formats of c++11 attribute arguments
31606880f492365cc4fa4c941aa83688635003ee7498Michael Han        ConsumeParen();
31616880f492365cc4fa4c941aa83688635003ee7498Michael Han        SkipUntil(tok::r_paren, false);
3162bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
31636880f492365cc4fa4c941aa83688635003ee7498Michael Han    }
3164bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
31656880f492365cc4fa4c941aa83688635003ee7498Michael Han    if (!AttrParsed)
3166e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      attrs.addNew(AttrName,
3167e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                   SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc,
3168e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                               AttrLoc),
3169e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                   ScopeName, ScopeLoc, 0,
317093f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt                   SourceLocation(), 0, 0, AttributeList::AS_CXX11);
31716ee326af4e77e6f05973486097884d7431f2108dRichard Smith
3172c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    if (Tok.is(tok::ellipsis)) {
31736ee326af4e77e6f05973486097884d7431f2108dRichard Smith      ConsumeToken();
31746880f492365cc4fa4c941aa83688635003ee7498Michael Han
31756880f492365cc4fa4c941aa83688635003ee7498Michael Han      Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis)
31766880f492365cc4fa4c941aa83688635003ee7498Michael Han        << AttrName->getName();
3177c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    }
3178bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
3179bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
3180bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
3181bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
31823497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne  if (endLoc)
31833497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne    *endLoc = Tok.getLocation();
3184bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
3185bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
31863497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne}
31873497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne
31882edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt/// ParseCXX11Attributes - Parse a C++11 attribute-specifier-seq.
31893497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne///
31903497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// attribute-specifier-seq:
31913497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne///       attribute-specifier-seq[opt] attribute-specifier
3192c56298d87a9df507805a548d7d515e8b511df2c0Richard Smithvoid Parser::ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
31933497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne                                  SourceLocation *endLoc) {
3194672edb0a04a5273e3a501f3b196844c125290780Richard Smith  assert(getLangOpts().CPlusPlus11);
3195672edb0a04a5273e3a501f3b196844c125290780Richard Smith
31963497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne  SourceLocation StartLoc = Tok.getLocation(), Loc;
31973497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne  if (!endLoc)
31983497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne    endLoc = &Loc;
31993497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne
32008828ee7faa42f889ade3bb635dc5f1338be671b1Douglas Gregor  do {
3201c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    ParseCXX11AttributeSpecifier(attrs, endLoc);
32026ee326af4e77e6f05973486097884d7431f2108dRichard Smith  } while (isCXX11AttributeSpecifier());
3203bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
32043497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne  attrs.Range = SourceRange(StartLoc, *endLoc);
3205bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
3206bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
3207334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ParseMicrosoftAttributes - Parse a Microsoft attribute [Attr]
3208334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///
3209334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute:
3210334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             '[' token-seq ']'
3211334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///
3212334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute-seq:
3213334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             ms-attribute[opt]
3214334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             ms-attribute ms-attribute-seq
32157f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCallvoid Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs,
32167f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                      SourceLocation *endLoc) {
3217334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
3218334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet
3219334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  while (Tok.is(tok::l_square)) {
32206ee326af4e77e6f05973486097884d7431f2108dRichard Smith    // FIXME: If this is actually a C++11 attribute, parse it as one.
3221334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    ConsumeBracket();
3222334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    SkipUntil(tok::r_square, true, true);
32237f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    if (endLoc) *endLoc = Tok.getLocation();
3224334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
3225334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  }
3226334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet}
3227563a645de82231a55e221fe655b7188bf8369662Francois Pichet
3228563a645de82231a55e221fe655b7188bf8369662Francois Pichetvoid Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
3229563a645de82231a55e221fe655b7188bf8369662Francois Pichet                                                    AccessSpecifier& CurAS) {
32303896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  IfExistsCondition Result;
3231563a645de82231a55e221fe655b7188bf8369662Francois Pichet  if (ParseMicrosoftIfExistsCondition(Result))
3232563a645de82231a55e221fe655b7188bf8369662Francois Pichet    return;
3233563a645de82231a55e221fe655b7188bf8369662Francois Pichet
32343896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  BalancedDelimiterTracker Braces(*this, tok::l_brace);
32353896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  if (Braces.consumeOpen()) {
3236563a645de82231a55e221fe655b7188bf8369662Francois Pichet    Diag(Tok, diag::err_expected_lbrace);
3237563a645de82231a55e221fe655b7188bf8369662Francois Pichet    return;
3238563a645de82231a55e221fe655b7188bf8369662Francois Pichet  }
3239563a645de82231a55e221fe655b7188bf8369662Francois Pichet
32403896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  switch (Result.Behavior) {
32413896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Parse:
32423896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    // Parse the declarations below.
32433896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    break;
32443896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
32453896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Dependent:
32463896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
32473896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor      << Result.IsIfExists;
32483896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    // Fall through to skip.
32493896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
32503896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Skip:
32513896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    Braces.skipToEnd();
3252563a645de82231a55e221fe655b7188bf8369662Francois Pichet    return;
3253563a645de82231a55e221fe655b7188bf8369662Francois Pichet  }
3254563a645de82231a55e221fe655b7188bf8369662Francois Pichet
32553896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
3256563a645de82231a55e221fe655b7188bf8369662Francois Pichet    // __if_exists, __if_not_exists can nest.
3257563a645de82231a55e221fe655b7188bf8369662Francois Pichet    if ((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists))) {
3258563a645de82231a55e221fe655b7188bf8369662Francois Pichet      ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
3259563a645de82231a55e221fe655b7188bf8369662Francois Pichet      continue;
3260563a645de82231a55e221fe655b7188bf8369662Francois Pichet    }
3261563a645de82231a55e221fe655b7188bf8369662Francois Pichet
3262563a645de82231a55e221fe655b7188bf8369662Francois Pichet    // Check for extraneous top-level semicolon.
3263563a645de82231a55e221fe655b7188bf8369662Francois Pichet    if (Tok.is(tok::semi)) {
3264eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith      ConsumeExtraSemi(InsideStruct, TagType);
3265563a645de82231a55e221fe655b7188bf8369662Francois Pichet      continue;
3266563a645de82231a55e221fe655b7188bf8369662Francois Pichet    }
3267563a645de82231a55e221fe655b7188bf8369662Francois Pichet
3268563a645de82231a55e221fe655b7188bf8369662Francois Pichet    AccessSpecifier AS = getAccessSpecifierIfPresent();
3269563a645de82231a55e221fe655b7188bf8369662Francois Pichet    if (AS != AS_none) {
3270563a645de82231a55e221fe655b7188bf8369662Francois Pichet      // Current token is a C++ access specifier.
3271563a645de82231a55e221fe655b7188bf8369662Francois Pichet      CurAS = AS;
3272563a645de82231a55e221fe655b7188bf8369662Francois Pichet      SourceLocation ASLoc = Tok.getLocation();
3273563a645de82231a55e221fe655b7188bf8369662Francois Pichet      ConsumeToken();
3274563a645de82231a55e221fe655b7188bf8369662Francois Pichet      if (Tok.is(tok::colon))
3275563a645de82231a55e221fe655b7188bf8369662Francois Pichet        Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
3276563a645de82231a55e221fe655b7188bf8369662Francois Pichet      else
3277563a645de82231a55e221fe655b7188bf8369662Francois Pichet        Diag(Tok, diag::err_expected_colon);
3278563a645de82231a55e221fe655b7188bf8369662Francois Pichet      ConsumeToken();
3279563a645de82231a55e221fe655b7188bf8369662Francois Pichet      continue;
3280563a645de82231a55e221fe655b7188bf8369662Francois Pichet    }
3281563a645de82231a55e221fe655b7188bf8369662Francois Pichet
3282563a645de82231a55e221fe655b7188bf8369662Francois Pichet    // Parse all the comma separated declarators.
32835f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    ParseCXXClassMemberDeclaration(CurAS, 0);
3284563a645de82231a55e221fe655b7188bf8369662Francois Pichet  }
32853896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
32863896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  Braces.consumeClose();
3287563a645de82231a55e221fe655b7188bf8369662Francois Pichet}
3288