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"
18ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo#include "clang/AST/DeclTemplate.h"
19500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h"
2019510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
2119510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/ParsedTemplate.h"
22f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall#include "clang/Sema/PrettyDeclStackTrace.h"
2355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Scope.h"
24e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall#include "clang/Sema/SemaDiagnostic.h"
258fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer#include "llvm/ADT/SmallString.h"
268f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattnerusing namespace clang;
278f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner
288f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// ParseNamespace - We know that the current token is a namespace keyword. This
29d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// may either be a top level namespace or a block-level namespace alias. If
30d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// there was an inline keyword, it has already been parsed.
318f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
328f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       namespace-definition: [C++ 7.3: basic.namespace]
338f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         named-namespace-definition
348f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         unnamed-namespace-definition
358f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
368f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       unnamed-namespace-definition:
37d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' attributes[opt] '{' namespace-body '}'
388f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
398f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       named-namespace-definition:
408f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         original-namespace-definition
418f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         extension-namespace-definition
428f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
438f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       original-namespace-definition:
44d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' identifier attributes[opt]
45d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///             '{' namespace-body '}'
468f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
478f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       extension-namespace-definition:
48d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' original-namespace-name
49d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///             '{' namespace-body '}'
501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
518f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       namespace-alias-definition:  [C++ 7.3.2: namespace.alias]
528f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         'namespace' identifier '=' qualified-namespace-specifier ';'
538f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
54d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespace(unsigned Context,
55d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl                             SourceLocation &DeclEnd,
56d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl                             SourceLocation InlineLoc) {
5704d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
588f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation NamespaceLoc = ConsumeToken();  // eat the 'namespace'.
599735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian  ObjCDeclContextSwitch ObjCDC(*this);
60a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian
6149f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
6223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteNamespaceDecl(getCurScope());
637d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
647d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
6549f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
66193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
678f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation IdentLoc;
688f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  IdentifierInfo *Ident = 0;
69f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  std::vector<SourceLocation> ExtraIdentLoc;
70f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  std::vector<IdentifierInfo*> ExtraIdent;
71f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  std::vector<SourceLocation> ExtraNamespaceLoc;
726a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
736a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  Token attrTok;
741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7504d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  if (Tok.is(tok::identifier)) {
768f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    Ident = Tok.getIdentifierInfo();
778f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    IdentLoc = ConsumeToken();  // eat the identifier.
78f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    while (Tok.is(tok::coloncolon) && NextToken().is(tok::identifier)) {
79f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ExtraNamespaceLoc.push_back(ConsumeToken());
80f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ExtraIdent.push_back(Tok.getIdentifierInfo());
81f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ExtraIdentLoc.push_back(ConsumeToken());
82f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
838f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  }
841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
858f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  // Read label attributes, if present.
860b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
876a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::kw___attribute)) {
886a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor    attrTok = Tok;
897f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
906a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
926a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::equal)) {
93e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber    if (Ident == 0) {
94e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber      Diag(Tok, diag::err_expected_ident);
95e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber      // Skip to end of the definition and eat the ';'.
96e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber      SkipUntil(tok::semi);
97e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber      return 0;
98e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber    }
997f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    if (!attrs.empty())
1006a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor      Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
101d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl    if (InlineLoc.isValid())
102d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl      Diag(InlineLoc, diag::err_inline_namespace_alias)
103d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl          << FixItHint::CreateRemoval(InlineLoc);
1049735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian    return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
1056a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
1061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
107f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
1084a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_brace);
1094a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.consumeOpen()) {
110f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    if (!ExtraIdent.empty()) {
111f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
112f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back());
113f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Diag(Tok, Ident ? diag::err_expected_lbrace :
1155144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner         diag::err_expected_ident_lbrace);
116d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
1175144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  }
1181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() ||
12023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      getCurScope()->isInObjcMethodScope() || getCurScope()->getBlockParent() ||
12123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      getCurScope()->getFnParent()) {
122f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    if (!ExtraIdent.empty()) {
123f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
124f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back());
125f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
1264a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope);
12795f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor    SkipUntil(tok::r_brace, false);
128d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
12995f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor  }
13095f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor
131f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  if (!ExtraIdent.empty()) {
132f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    TentativeParsingAction TPA(*this);
133f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    SkipUntil(tok::r_brace, /*StopAtSemi*/false, /*DontConsume*/true);
134f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    Token rBraceToken = Tok;
135f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    TPA.Revert();
136f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
137f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    if (!rBraceToken.is(tok::r_brace)) {
138f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
139f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back());
140f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    } else {
1419910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer      std::string NamespaceFix;
142f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      for (std::vector<IdentifierInfo*>::iterator I = ExtraIdent.begin(),
143f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu           E = ExtraIdent.end(); I != E; ++I) {
144f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu        NamespaceFix += " { namespace ";
145f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu        NamespaceFix += (*I)->getName();
146f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      }
1479910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer
148f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      std::string RBraces;
1499910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer      for (unsigned i = 0, e = ExtraIdent.size(); i != e; ++i)
150f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu        RBraces +=  "} ";
1519910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer
152f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
153f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << FixItHint::CreateReplacement(SourceRange(ExtraNamespaceLoc.front(),
154f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                                      ExtraIdentLoc.back()),
155f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                          NamespaceFix)
156f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu          << FixItHint::CreateInsertion(rBraceToken.getLocation(), RBraces);
157f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
158f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  }
159f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
16088e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl  // If we're still good, complain about inline namespaces in non-C++0x now.
1617fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith  if (InlineLoc.isValid())
16280ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith    Diag(InlineLoc, getLangOpts().CPlusPlus11 ?
1637fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith         diag::warn_cxx98_compat_inline_namespace : diag::ext_inline_namespace);
16488e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl
1655144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Enter a scope for the namespace.
1665144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  ParseScope NamespaceScope(this, Scope::DeclScope);
1672d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
168d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *NamespcDecl =
169acba90f30876b4140b738f0d3dd0e50724053a96Abramo Bagnara    Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, NamespaceLoc,
1704a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                   IdentLoc, Ident, T.getOpenLocation(),
1714a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                   attrs.getList());
1722d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
173f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc,
174f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing namespace");
1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
176f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  // Parse the contents of the namespace.  This includes parsing recovery on
177f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  // any improperly nested namespaces.
178f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  ParseInnerNamespace(ExtraIdentLoc, ExtraIdent, ExtraNamespaceLoc, 0,
1794a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                      InlineLoc, attrs, T);
1801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1815144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Leave the namespace scope.
1825144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  NamespaceScope.Exit();
1838ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis
1844a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  DeclEnd = T.getCloseLocation();
1854a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  Actions.ActOnFinishNamespaceDef(NamespcDecl, DeclEnd);
1862d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
1875144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  return NamespcDecl;
1888f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner}
189c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
190f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu/// ParseInnerNamespace - Parse the contents of a namespace.
191f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieuvoid Parser::ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc,
192f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 std::vector<IdentifierInfo*>& Ident,
193f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 std::vector<SourceLocation>& NamespaceLoc,
194f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 unsigned int index, SourceLocation& InlineLoc,
195f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                 ParsedAttributes& attrs,
1964a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                 BalancedDelimiterTracker &Tracker) {
197f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  if (index == Ident.size()) {
198f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
199f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ParsedAttributesWithRange attrs(AttrFactory);
2004e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith      MaybeParseCXX11Attributes(attrs);
201f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      MaybeParseMicrosoftAttributes(attrs);
202f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu      ParseExternalDeclaration(attrs);
203f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    }
2044a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor
2054a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    // The caller is what called check -- we are simply calling
2064a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    // the close for it.
2074a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    Tracker.consumeClose();
208f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
209f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    return;
210f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  }
211f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
212f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  // Parse improperly nested namespaces.
213f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  ParseScope NamespaceScope(this, Scope::DeclScope);
214f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  Decl *NamespcDecl =
215f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu    Actions.ActOnStartNamespaceDef(getCurScope(), SourceLocation(),
216f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu                                   NamespaceLoc[index], IdentLoc[index],
2174a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                   Ident[index], Tracker.getOpenLocation(),
2184a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                   attrs.getList());
219f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
220f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  ParseInnerNamespace(IdentLoc, Ident, NamespaceLoc, ++index, InlineLoc,
2214a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                      attrs, Tracker);
222f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
223f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu  NamespaceScope.Exit();
224f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
2254a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  Actions.ActOnFinishNamespaceDef(NamespcDecl, Tracker.getCloseLocation());
226f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu}
227f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu
228f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
229f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// alias definition.
230f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson///
231d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
2320b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  SourceLocation AliasLoc,
2330b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  IdentifierInfo *Alias,
2340b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  SourceLocation &DeclEnd) {
235f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  assert(Tok.is(tok::equal) && "Not equal token");
2361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
237f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  ConsumeToken(); // eat the '='.
2381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23949f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
24023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteNamespaceAliasDecl(getCurScope());
2417d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
2427d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
24349f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
244193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
245f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  CXXScopeSpec SS;
246f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse (optional) nested-name-specifier.
247efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
248f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
249f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
250f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    Diag(Tok, diag::err_expected_namespace_name);
251f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    // Skip to end of the definition and eat the ';'.
252f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    SkipUntil(tok::semi);
253d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
254f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  }
255f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
256f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse identifier.
25703bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  IdentifierInfo *Ident = Tok.getIdentifierInfo();
25803bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  SourceLocation IdentLoc = ConsumeToken();
2591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
260f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Eat the ';'.
26197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
2626869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name,
2636869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner                   "", tok::semi);
2641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
26523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc, Alias,
26603bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson                                        SS, IdentLoc, Ident);
267f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson}
268f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
269c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal
270c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen.
271c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
272c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///       linkage-specification: [C++ 7.5p2: dcl.link]
273c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal '{' declaration-seq[opt] '}'
274c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal declaration
275c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
2767d64271b162eaf5cae264ff64465b28af623dc17Chris LattnerDecl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
277c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor  assert(Tok.is(tok::string_literal) && "Not a string literal!");
278f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<8> LangBuffer;
279453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  bool Invalid = false;
2805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid);
281453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  if (Invalid)
282d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
283c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
28499831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  // FIXME: This is incorrect: linkage-specifiers are parsed in translation
28599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  // phase 7, so string-literal concatenation is supposed to occur.
28699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  //   extern "" "C" "" "+" "+" { } is legal.
28799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  if (Tok.hasUDSuffix())
28899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith    Diag(Tok, diag::err_invalid_string_udl);
289c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  SourceLocation Loc = ConsumeStringToken();
290c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
291074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  ParseScope LinkageScope(this, Scope::DeclScope);
292d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *LinkageSpec
29323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    = Actions.ActOnStartLinkageSpecification(getCurScope(),
294a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                             DS.getSourceRange().getBegin(),
295d56638180014e60538cd666cd11fde6d4698e051Benjamin Kramer                                             Loc, Lang,
296a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                      Tok.is(tok::l_brace) ? Tok.getLocation()
297074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                           : SourceLocation());
298074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
2990b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributesWithRange attrs(AttrFactory);
3004e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith  MaybeParseCXX11Attributes(attrs);
3017f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseMicrosoftAttributes(attrs);
302193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
303074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (Tok.isNot(tok::l_brace)) {
304f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // Reset the source range in DS, as the leading "extern"
305f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // does not really belong to the inner declaration ...
306f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    DS.SetRangeStart(SourceLocation());
307f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    DS.SetRangeEnd(SourceLocation());
308f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // ... but anyway remember that such an "extern" was seen.
30935f9a196ef897b9559de25aaecd957208f0b4f59Abramo Bagnara    DS.setExternInLinkageSpec(true);
3107f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseExternalDeclaration(attrs, &DS);
31123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
312074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                   SourceLocation());
3131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
314f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor
31563a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor  DS.abort();
31663a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor
3177f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  ProhibitAttributes(attrs);
318bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
3194a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_brace);
3204a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
321f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
3220b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    ParsedAttributesWithRange attrs(AttrFactory);
3234e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith    MaybeParseCXX11Attributes(attrs);
3247f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseMicrosoftAttributes(attrs);
3257f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseExternalDeclaration(attrs);
326f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  }
327c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
3284a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
3297d64271b162eaf5cae264ff64465b28af623dc17Chris Lattner  return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
3304a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                                 T.getCloseLocation());
331c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner}
332e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
333f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
334f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'.
335d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
33678b810559d89e996e00684335407443936ce34a1John McCall                                         const ParsedTemplateInfo &TemplateInfo,
33778b810559d89e996e00684335407443936ce34a1John McCall                                               SourceLocation &DeclEnd,
338c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                             ParsedAttributesWithRange &attrs,
339c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                               Decl **OwnedType) {
340f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_using) && "Not using token");
3419735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian  ObjCDeclContextSwitch ObjCDC(*this);
3429735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian
343f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'using'.
344f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation UsingLoc = ConsumeToken();
345f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
34649f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
34723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteUsing(getCurScope());
3487d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
3497d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
35049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
351193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
35278b810559d89e996e00684335407443936ce34a1John McCall  // 'using namespace' means this is a using-directive.
35378b810559d89e996e00684335407443936ce34a1John McCall  if (Tok.is(tok::kw_namespace)) {
35478b810559d89e996e00684335407443936ce34a1John McCall    // Template parameters are always an error here.
35578b810559d89e996e00684335407443936ce34a1John McCall    if (TemplateInfo.Kind) {
35678b810559d89e996e00684335407443936ce34a1John McCall      SourceRange R = TemplateInfo.getSourceRange();
35778b810559d89e996e00684335407443936ce34a1John McCall      Diag(UsingLoc, diag::err_templated_using_directive)
35878b810559d89e996e00684335407443936ce34a1John McCall        << R << FixItHint::CreateRemoval(R);
35978b810559d89e996e00684335407443936ce34a1John McCall    }
36078b810559d89e996e00684335407443936ce34a1John McCall
3619735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian    return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
36278b810559d89e996e00684335407443936ce34a1John McCall  }
363bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
364162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  // Otherwise, it must be a using-declaration or an alias-declaration.
36578b810559d89e996e00684335407443936ce34a1John McCall
36678b810559d89e996e00684335407443936ce34a1John McCall  // Using declarations can't have attributes.
3677f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  ProhibitAttributes(attrs);
3682f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner
3699735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian  return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd,
370a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian                                    AS_none, OwnedType);
371f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
372f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
373f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes
374f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed.
375f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
376f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       using-directive: [C++ 7.3.p4: namespace.udir]
377f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
378f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name ;
379f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive:
380f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
381f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name attributes[opt] ;
382f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
383d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirective(unsigned Context,
38478b810559d89e996e00684335407443936ce34a1John McCall                                  SourceLocation UsingLoc,
38578b810559d89e996e00684335407443936ce34a1John McCall                                  SourceLocation &DeclEnd,
3867f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                  ParsedAttributes &attrs) {
387f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
388f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
389f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'namespace'.
390f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation NamespcLoc = ConsumeToken();
391f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
39249f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
39323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteUsingDirective(getCurScope());
3947d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    cutOffParsing();
3957d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return 0;
39649f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
397193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
398f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  CXXScopeSpec SS;
399f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse (optional) nested-name-specifier.
400efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
401f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
402f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  IdentifierInfo *NamespcName = 0;
403f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation IdentLoc = SourceLocation();
404f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
405f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse namespace-name.
406823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
407f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    Diag(Tok, diag::err_expected_namespace_name);
408f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // If there was invalid namespace name, skip to end of decl, and eat ';'.
409f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    SkipUntil(tok::semi);
410f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
411d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
412f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  }
4131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
414823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse identifier.
415823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  NamespcName = Tok.getIdentifierInfo();
416823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  IdentLoc = ConsumeToken();
4171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
418823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse (optional) attributes (most likely GNU strong-using extension).
419bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  bool GNUAttr = false;
420bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Tok.is(tok::kw___attribute)) {
421bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    GNUAttr = true;
4227f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
423bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
425823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Eat ';'.
42697144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
4276869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi,
4289ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                   GNUAttr ? diag::err_expected_semi_after_attribute_list
4299ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                           : diag::err_expected_semi_after_namespace_name,
4309ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                   "", tok::semi);
431f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
43223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
4337f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                     IdentLoc, NamespcName, attrs.getList());
434f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
435f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
436162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration.
437162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// Assumes that 'using' was already seen.
438f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
439f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///     using-declaration: [C++ 7.3.p3: namespace.udecl]
440f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       'using' 'typename'[opt] ::[opt] nested-name-specifier
4419cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///               unqualified-id
4429cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///       'using' :: unqualified-id
443f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
444d03de6aaa312d57dcd6e2bc76bed1e89f5c5019dRichard Smith///     alias-declaration: C++11 [dcl.dcl]p1
445d03de6aaa312d57dcd6e2bc76bed1e89f5c5019dRichard Smith///       'using' identifier attribute-specifier-seq[opt] = type-id ;
446162e1c1b487352434552147967c3dd296ebee2f7Richard Smith///
447d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDeclaration(unsigned Context,
44878b810559d89e996e00684335407443936ce34a1John McCall                                    const ParsedTemplateInfo &TemplateInfo,
44978b810559d89e996e00684335407443936ce34a1John McCall                                    SourceLocation UsingLoc,
45078b810559d89e996e00684335407443936ce34a1John McCall                                    SourceLocation &DeclEnd,
451c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                    AccessSpecifier AS,
452c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith                                    Decl **OwnedType) {
4539cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  CXXScopeSpec SS;
4547ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall  SourceLocation TypenameLoc;
4558d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella  bool HasTypenameKeyword = false;
4566b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith  ParsedAttributesWithRange Attrs(AttrFactory);
4572edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
4582edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  // FIXME: Simply skip the attributes and diagnose, don't bother parsing them.
4596b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith  MaybeParseCXX11Attributes(Attrs);
4606b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith  ProhibitAttributes(Attrs);
4616b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith  Attrs.clear();
4626b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith  Attrs.Range = SourceRange();
4639cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
4649cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Ignore optional 'typename'.
46512c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // FIXME: This is wrong; we should parse this as a typename-specifier.
4669cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_typename)) {
4676b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith    TypenameLoc = ConsumeToken();
4688d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella    HasTypenameKeyword = true;
4699cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
4709cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
4719cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Parse nested-name-specifier.
4722db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith  IdentifierInfo *LastII = 0;
4732db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false,
4742db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith                                 /*MayBePseudoDtor=*/0, /*IsTypename=*/false,
4752db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith                                 /*LastII=*/&LastII);
4769cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
4779cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Check nested-name specifier.
4789cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (SS.isInvalid()) {
4799cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
480d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
4819cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4832db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith  SourceLocation TemplateKWLoc;
4842db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith  UnqualifiedId Name;
4852db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith
486193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  // Parse the unqualified-id. We allow parsing of both constructor and
48712c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // destructor names and allow the action module to diagnose any semantic
48812c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // errors.
4892db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith  //
4902db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith  // C++11 [class.qual]p2:
4912db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith  //   [...] in a using-declaration that is a member-declaration, if the name
4922db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith  //   specified after the nested-name-specifier is the same as the identifier
4932db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith  //   or the simple-template-id's template-name in the last component of the
4942db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith  //   nested-name-specifier, the name is [...] considered to name the
4952db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith  //   constructor.
4962db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith  if (getLangOpts().CPlusPlus11 && Context == Declarator::MemberContext &&
4972db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith      Tok.is(tok::identifier) && NextToken().is(tok::semi) &&
4982db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith      SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() &&
4992db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith      !SS.getScopeRep()->getAsNamespace() &&
5002db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith      !SS.getScopeRep()->getAsNamespaceAlias()) {
5012db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith    SourceLocation IdLoc = ConsumeToken();
5022db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith    ParsedType Type = Actions.getInheritingConstructorName(SS, IdLoc, *LastII);
5032db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith    Name.setConstructorName(Type, IdLoc, IdLoc);
5042db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith  } else if (ParseUnqualifiedId(SS, /*EnteringContext=*/ false,
5052db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith                                /*AllowDestructorName=*/ true,
5062db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith                                /*AllowConstructorName=*/ true, ParsedType(),
5072db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith                                TemplateKWLoc, Name)) {
5089cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
509d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
5109cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
511193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
5126b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith  MaybeParseCXX11Attributes(Attrs);
513162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
514162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  // Maybe this is an alias-declaration.
515162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  bool IsAliasDecl = Tok.is(tok::equal);
516162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  TypeResult TypeAlias;
517162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (IsAliasDecl) {
5186b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith    // TODO: Can GNU attributes appear here?
519162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    ConsumeToken();
520162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
52180ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith    Diag(Tok.getLocation(), getLangOpts().CPlusPlus11 ?
5227fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith         diag::warn_cxx98_compat_alias_declaration :
5237fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith         diag::ext_alias_declaration);
524162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
5253e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    // Type alias templates cannot be specialized.
5263e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    int SpecKind = -1;
527536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&
528536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith        Name.getKind() == UnqualifiedId::IK_TemplateId)
5293e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 0;
5303e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)
5313e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 1;
5323e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
5333e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 2;
5343e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (SpecKind != -1) {
5353e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SourceRange Range;
5363e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      if (SpecKind == 0)
5373e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        Range = SourceRange(Name.TemplateId->LAngleLoc,
5383e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                            Name.TemplateId->RAngleLoc);
5393e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      else
5403e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        Range = TemplateInfo.getSourceRange();
5413e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      Diag(Range.getBegin(), diag::err_alias_declaration_specialization)
5423e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        << SpecKind << Range;
5433e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SkipUntil(tok::semi);
5443e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      return 0;
5453e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    }
5463e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
547162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    // Name must be an identifier.
548162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    if (Name.getKind() != UnqualifiedId::IK_Identifier) {
549162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(Name.StartLocation, diag::err_alias_declaration_not_identifier);
550162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      // No removal fixit: can't recover from this.
551162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      SkipUntil(tok::semi);
552162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      return 0;
5538d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella    } else if (HasTypenameKeyword)
554162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(TypenameLoc, diag::err_alias_declaration_not_identifier)
555162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        << FixItHint::CreateRemoval(SourceRange(TypenameLoc,
556162e1c1b487352434552147967c3dd296ebee2f7Richard Smith                             SS.isNotEmpty() ? SS.getEndLoc() : TypenameLoc));
557162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    else if (SS.isNotEmpty())
558162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
559162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        << FixItHint::CreateRemoval(SS.getRange());
560162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
5613e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    TypeAlias = ParseTypeName(0, TemplateInfo.Kind ?
5623e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                              Declarator::AliasTemplateContext :
5636b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith                              Declarator::AliasDeclContext, AS, OwnedType,
5646b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith                              &Attrs);
5652edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  } else {
5662edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt    // C++11 attributes are not allowed on a using-declaration, but GNU ones
5672edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt    // are.
5686b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith    ProhibitAttributes(Attrs);
5692edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
570162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    // Parse (optional) attributes (most likely GNU strong-using extension).
5716b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith    MaybeParseGNUAttributes(Attrs);
5722edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  }
5731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5749cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Eat ';'.
5759cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  DeclEnd = Tok.getLocation();
5769cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
5776b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith                   !Attrs.empty() ? "attributes list" :
578162e1c1b487352434552147967c3dd296ebee2f7Richard Smith                   IsAliasDecl ? "alias declaration" : "using declaration",
57912c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                   tok::semi);
5809cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
58178b810559d89e996e00684335407443936ce34a1John McCall  // Diagnose an attempt to declare a templated using-declaration.
582d03de6aaa312d57dcd6e2bc76bed1e89f5c5019dRichard Smith  // In C++11, alias-declarations can be templates:
583162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  //   template <...> using id = type;
5843e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  if (TemplateInfo.Kind && !IsAliasDecl) {
58578b810559d89e996e00684335407443936ce34a1John McCall    SourceRange R = TemplateInfo.getSourceRange();
58678b810559d89e996e00684335407443936ce34a1John McCall    Diag(UsingLoc, diag::err_templated_using_declaration)
58778b810559d89e996e00684335407443936ce34a1John McCall      << R << FixItHint::CreateRemoval(R);
58878b810559d89e996e00684335407443936ce34a1John McCall
58978b810559d89e996e00684335407443936ce34a1John McCall    // Unfortunately, we have to bail out instead of recovering by
59078b810559d89e996e00684335407443936ce34a1John McCall    // ignoring the parameters, just in case the nested name specifier
59178b810559d89e996e00684335407443936ce34a1John McCall    // depends on the parameters.
59278b810559d89e996e00684335407443936ce34a1John McCall    return 0;
59378b810559d89e996e00684335407443936ce34a1John McCall  }
59478b810559d89e996e00684335407443936ce34a1John McCall
595480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  // "typename" keyword is allowed for identifiers only,
596480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  // because it may be a type definition.
5978d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella  if (HasTypenameKeyword && Name.getKind() != UnqualifiedId::IK_Identifier) {
598480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor    Diag(Name.getSourceRange().getBegin(), diag::err_typename_identifiers_only)
599480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor      << FixItHint::CreateRemoval(SourceRange(TypenameLoc));
6008d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella    // Proceed parsing, but reset the HasTypenameKeyword flag.
6018d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella    HasTypenameKeyword = false;
602480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  }
603480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor
6043e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  if (IsAliasDecl) {
6053e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
6065354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer    MultiTemplateParamsArg TemplateParamsArg(
6073e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      TemplateParams ? TemplateParams->data() : 0,
6083e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      TemplateParams ? TemplateParams->size() : 0);
6093e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,
6106b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith                                         UsingLoc, Name, Attrs.getList(),
6116b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith                                         TypeAlias);
6123e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
613162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
6148d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella  return Actions.ActOnUsingDeclaration(getCurScope(), AS,
6158d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella                                       /* HasUsingKeyword */ true, UsingLoc,
6168d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella                                       SS, Name, Attrs.getList(),
6178d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella                                       HasTypenameKeyword, TypenameLoc);
618f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
619f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
620ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer/// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration.
621511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
622c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// [C++0x] static_assert-declaration:
623c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///           static_assert ( constant-expression  ,  string-literal  ) ;
624c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///
625ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer/// [C11]   static_assert-declaration:
626c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///           _Static_assert ( constant-expression  ,  string-literal  ) ;
627511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
628d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
629c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne  assert((Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) &&
630c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne         "Not a static_assert declaration");
631c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne
6324e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11)
633ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer    Diag(Tok, diag::ext_c11_static_assert);
634841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith  if (Tok.is(tok::kw_static_assert))
635841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith    Diag(Tok, diag::warn_cxx98_compat_static_assert);
636c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne
637511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation StaticAssertLoc = ConsumeToken();
6381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6394a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
6404a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.consumeOpen()) {
641511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_lparen);
6423686c71ff92e4357a78993a16a27185f16ab6234Richard Smith    SkipMalformedDecl();
643d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
644511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
6451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
64660d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult AssertExpr(ParseConstantExpression());
647511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (AssertExpr.isInvalid()) {
6483686c71ff92e4357a78993a16a27185f16ab6234Richard Smith    SkipMalformedDecl();
649d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
650511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
6511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
652ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
653d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
654ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson
6550cc323c6bed7206f9743a9775ec8d9cb90655f9cRichard Smith  if (!isTokenStringLiteral()) {
65697f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs    Diag(Tok, diag::err_expected_string_literal)
65797f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs      << /*Source='static_assert'*/1;
6583686c71ff92e4357a78993a16a27185f16ab6234Richard Smith    SkipMalformedDecl();
659d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
660511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
6611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
66260d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult AssertMessage(ParseStringLiteralExpression());
66399831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  if (AssertMessage.isInvalid()) {
6643686c71ff92e4357a78993a16a27185f16ab6234Richard Smith    SkipMalformedDecl();
665d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
66699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith  }
667511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
6684a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
6691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
67097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
6719ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor  ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert);
672511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
6739ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc,
6749ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                              AssertExpr.take(),
675a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                              AssertMessage.take(),
6764a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                              T.getCloseLocation());
677511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson}
678511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
679a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith/// ParseDecltypeSpecifier - Parse a C++11 decltype specifier.
6806fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
6816fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 'decltype' ( expression )
682a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith/// 'decltype' ( 'auto' )      [C++1y]
6836fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
68442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid BlaikieSourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
68542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  assert((Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype))
68642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie           && "Not a decltype specifier");
68742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
68842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  ExprResult Result;
68942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  SourceLocation StartLoc = Tok.getLocation();
69042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  SourceLocation EndLoc;
6911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
69242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  if (Tok.is(tok::annot_decltype)) {
69342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    Result = getExprAnnotation(Tok);
69442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    EndLoc = Tok.getAnnotationEndLoc();
69542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    ConsumeToken();
69642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    if (Result.isInvalid()) {
69742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      DS.SetTypeSpecError();
69842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      return EndLoc;
69942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    }
70042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  } else {
701c7b5543ad32a5c265c02e71b2a6f9856440ed13fRichard Smith    if (Tok.getIdentifierInfo()->isStr("decltype"))
702c7b5543ad32a5c265c02e71b2a6f9856440ed13fRichard Smith      Diag(Tok, diag::warn_cxx98_compat_decltype);
70339304fad1c8a7b7e64121e9ae544b18e460b682cRichard Smith
70442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    ConsumeToken();
7051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
70642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    BalancedDelimiterTracker T(*this, tok::l_paren);
70742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    if (T.expectAndConsume(diag::err_expected_lparen_after,
70842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie                           "decltype", tok::r_paren)) {
70942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      DS.SetTypeSpecError();
71042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      return T.getOpenLocation() == Tok.getLocation() ?
71142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie             StartLoc : T.getOpenLocation();
71242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    }
7131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
714a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith    // Check for C++1y 'decltype(auto)'.
715a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith    if (Tok.is(tok::kw_auto)) {
716a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith      // No need to disambiguate here: an expression can't start with 'auto',
717a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith      // because the typename-specifier in a function-style cast operation can't
718a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith      // be 'auto'.
719a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith      Diag(Tok.getLocation(),
720a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith           getLangOpts().CPlusPlus1y
721a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith             ? diag::warn_cxx11_compat_decltype_auto_type_specifier
722a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith             : diag::ext_decltype_auto_type_specifier);
723a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith      ConsumeToken();
724a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith    } else {
725a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith      // Parse the expression
726a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith
727a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith      // C++11 [dcl.type.simple]p4:
728a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith      //   The operand of the decltype specifier is an unevaluated operand.
729a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith      EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
730a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith                                                   0, /*IsDecltype=*/true);
731a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith      Result = ParseExpression();
732a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith      if (Result.isInvalid()) {
733a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith        DS.SetTypeSpecError();
734a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith        if (SkipUntil(tok::r_paren, /*StopAtSemi=*/true,
735a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith                      /*DontConsume=*/true)) {
736a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith          EndLoc = ConsumeParen();
7371e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis        } else {
738a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith          if (PP.isBacktrackEnabled() && Tok.is(tok::semi)) {
739a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith            // Backtrack to get the location of the last token before the semi.
740a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith            PP.RevertCachedTokens(2);
741a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith            ConsumeToken(); // the semi.
742a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith            EndLoc = ConsumeAnyToken();
743a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith            assert(Tok.is(tok::semi));
744a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith          } else {
745a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith            EndLoc = Tok.getLocation();
746a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith          }
7471e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis        }
748a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith        return EndLoc;
7491e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis      }
750a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith
751a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith      Result = Actions.ActOnDecltypeExpression(Result.take());
75242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    }
75342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
75442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    // Match the ')'
75542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    T.consumeClose();
75642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    if (T.getCloseLocation().isInvalid()) {
75742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      DS.SetTypeSpecError();
75842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      // FIXME: this should return the location of the last token
75942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      //        that was consumed (by "consumeClose()")
76042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie      return T.getCloseLocation();
76142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    }
76242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
76376f3f69db1416425070177243e9f390122c553e0Richard Smith    if (Result.isInvalid()) {
76476f3f69db1416425070177243e9f390122c553e0Richard Smith      DS.SetTypeSpecError();
76576f3f69db1416425070177243e9f390122c553e0Richard Smith      return T.getCloseLocation();
76676f3f69db1416425070177243e9f390122c553e0Richard Smith    }
76776f3f69db1416425070177243e9f390122c553e0Richard Smith
76842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    EndLoc = T.getCloseLocation();
76942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  }
770a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  assert(!Result.isInvalid());
7716fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
7726fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  const char *PrevSpec = 0;
773fec54013fcd0eb72642741584ca04c1bc292bef8John McCall  unsigned DiagID;
7746fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Check for duplicate type specifiers (e.g. "int decltype(a)").
775a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  if (Result.get()
776a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith        ? DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec,
777a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith                             DiagID, Result.release())
778a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith        : DS.SetTypeSpecType(DeclSpec::TST_decltype_auto, StartLoc, PrevSpec,
779a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith                             DiagID)) {
780fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
78142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    DS.SetTypeSpecError();
78242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  }
78342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  return EndLoc;
78442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie}
78542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
78642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikievoid Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec& DS,
78742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie                                               SourceLocation StartLoc,
78842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie                                               SourceLocation EndLoc) {
78942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  // make sure we have a token we can turn into an annotation token
79042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  if (PP.isBacktrackEnabled())
79142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    PP.RevertCachedTokens(1);
79242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  else
79342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie    PP.EnterToken(Tok);
79442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie
79542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  Tok.setKind(tok::annot_decltype);
796a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith  setExprAnnotation(Tok,
797a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith                    DS.getTypeSpecType() == TST_decltype ? DS.getRepAsExpr() :
798a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith                    DS.getTypeSpecType() == TST_decltype_auto ? ExprResult() :
799a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith                    ExprError());
80042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  Tok.setAnnotationEndLoc(EndLoc);
80142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  Tok.setLocation(StartLoc);
80242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  PP.AnnotateCachedTokens(Tok);
8036fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson}
8046fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
805db5d44b775c60166074acd184ca9f1981c10c2a7Sean Huntvoid Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) {
806db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  assert(Tok.is(tok::kw___underlying_type) &&
807db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt         "Not an underlying type specifier");
808db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
809db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  SourceLocation StartLoc = ConsumeToken();
8104a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
8114a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.expectAndConsume(diag::err_expected_lparen_after,
8124a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                       "__underlying_type", tok::r_paren)) {
813db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
814db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  }
815db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
816db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  TypeResult Result = ParseTypeName();
817db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  if (Result.isInvalid()) {
818db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    SkipUntil(tok::r_paren);
819db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
820db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  }
821db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
822db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  // Match the ')'
8234a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
8244a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.getCloseLocation().isInvalid())
825db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
826db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
827db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  const char *PrevSpec = 0;
828db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  unsigned DiagID;
829ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec,
830db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt                         DiagID, Result.release()))
831db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    Diag(StartLoc, DiagID) << PrevSpec;
8322d77634e839880704d51656bebd1d2daff661d4eEnea Zaffanella  DS.setTypeofParensRange(T.getRange());
833db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt}
834db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
83509048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// ParseBaseTypeSpecifier - Parse a C++ base-type-specifier which is either a
83609048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class name or decltype-specifier. Note that we only check that the result
83709048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// names a type; semantic analysis will need to verify that the type names a
83809048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class. The result is either a type or null, depending on whether a type
83909048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// name was found.
84042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///
841053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///       base-type-specifier: [C++11 class.derived]
84209048df0b3f472091b2204e531d6b6019244884bDavid Blaikie///         class-or-decltype
843053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///       class-or-decltype: [C++11 class.derived]
84409048df0b3f472091b2204e531d6b6019244884bDavid Blaikie///         nested-name-specifier[opt] class-name
84509048df0b3f472091b2204e531d6b6019244884bDavid Blaikie///         decltype-specifier
846053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///       class-name: [C++ class.name]
84742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///         identifier
8487f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor///         simple-template-id
8491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
850053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// In C++98, instead of base-type-specifier, we have:
851053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///
852053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///         ::[opt] nested-name-specifier[opt] class-name
85322216eb4fb0936d2488fc03abd285d135c36ff01David BlaikieParser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
85422216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie                                                  SourceLocation &EndLocation) {
8557fe3878a36750515fb9772414ecb2489cf149d19David Blaikie  // Ignore attempts to use typename
8567fe3878a36750515fb9772414ecb2489cf149d19David Blaikie  if (Tok.is(tok::kw_typename)) {
8577fe3878a36750515fb9772414ecb2489cf149d19David Blaikie    Diag(Tok, diag::err_expected_class_name_not_template)
8587fe3878a36750515fb9772414ecb2489cf149d19David Blaikie      << FixItHint::CreateRemoval(Tok.getLocation());
8597fe3878a36750515fb9772414ecb2489cf149d19David Blaikie    ConsumeToken();
8607fe3878a36750515fb9772414ecb2489cf149d19David Blaikie  }
8617fe3878a36750515fb9772414ecb2489cf149d19David Blaikie
862152aa4b87633754801598ee282e1a17c3ec49257David Blaikie  // Parse optional nested-name-specifier
863152aa4b87633754801598ee282e1a17c3ec49257David Blaikie  CXXScopeSpec SS;
864152aa4b87633754801598ee282e1a17c3ec49257David Blaikie  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
865152aa4b87633754801598ee282e1a17c3ec49257David Blaikie
866152aa4b87633754801598ee282e1a17c3ec49257David Blaikie  BaseLoc = Tok.getLocation();
867152aa4b87633754801598ee282e1a17c3ec49257David Blaikie
86822216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie  // Parse decltype-specifier
86942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  // tok == kw_decltype is just error recovery, it can only happen when SS
87042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  // isn't empty
87142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie  if (Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) {
872152aa4b87633754801598ee282e1a17c3ec49257David Blaikie    if (SS.isNotEmpty())
873152aa4b87633754801598ee282e1a17c3ec49257David Blaikie      Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype)
874152aa4b87633754801598ee282e1a17c3ec49257David Blaikie        << FixItHint::CreateRemoval(SS.getRange());
87522216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie    // Fake up a Declarator to use with ActOnTypeName.
87622216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie    DeclSpec DS(AttrFactory);
87722216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie
878b57775709666e50cd925f9fc589d0fd895fc79a6David Blaikie    EndLocation = ParseDecltypeSpecifier(DS);
87922216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie
88022216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie    Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
88122216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie    return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
88222216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie  }
88322216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie
8847f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  // Check whether we have a template-id that names a type.
8857f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  if (Tok.is(tok::annot_template_id)) {
88625a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
887d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor    if (TemplateId->Kind == TNK_Type_template ||
888d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor        TemplateId->Kind == TNK_Dependent_template_name) {
889059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
8907f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
8917f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
892b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      ParsedType Type = getTypeAnnotation(Tok);
8937f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      EndLocation = Tok.getAnnotationEndLoc();
8947f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      ConsumeToken();
89531a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor
89631a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      if (Type)
89731a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor        return Type;
89831a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      return true;
8997f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    }
9007f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
9017f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    // Fall through to produce an error below.
9027f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  }
9037f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
90442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  if (Tok.isNot(tok::identifier)) {
9051ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_class_name);
90631a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
90742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
90842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
90984d0a19828599e8623223632d59447fd498999cfDouglas Gregor  IdentifierInfo *Id = Tok.getIdentifierInfo();
91084d0a19828599e8623223632d59447fd498999cfDouglas Gregor  SourceLocation IdLoc = ConsumeToken();
91184d0a19828599e8623223632d59447fd498999cfDouglas Gregor
91284d0a19828599e8623223632d59447fd498999cfDouglas Gregor  if (Tok.is(tok::less)) {
91384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // It looks the user intended to write a template-id here, but the
91484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // template-name was wrong. Try to fix that.
91584d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateNameKind TNK = TNK_Type_template;
91684d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateTy Template;
91723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(),
918059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                             &SS, Template, TNK)) {
91984d0a19828599e8623223632d59447fd498999cfDouglas Gregor      Diag(IdLoc, diag::err_unknown_template_name)
92084d0a19828599e8623223632d59447fd498999cfDouglas Gregor        << Id;
92184d0a19828599e8623223632d59447fd498999cfDouglas Gregor    }
922193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
92384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (!Template)
92484d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
92584d0a19828599e8623223632d59447fd498999cfDouglas Gregor
926193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam    // Form the template name
92784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    UnqualifiedId TemplateName;
92884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateName.setIdentifier(Id, IdLoc);
929193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
93084d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // Parse the full template-id, then turn it into a type.
931e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara    if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
932e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                                TemplateName, true))
93384d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
93484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (TNK == TNK_Dependent_template_name)
935059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
936193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
93784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // If we didn't end up with a typename token, there's nothing more we
93884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // can do.
93984d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (Tok.isNot(tok::annot_typename))
94084d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
941193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
94284d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // Retrieve the type from the annotation token, consume that token, and
94384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // return.
94484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    EndLocation = Tok.getAnnotationEndLoc();
945b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    ParsedType Type = getTypeAnnotation(Tok);
94684d0a19828599e8623223632d59447fd498999cfDouglas Gregor    ConsumeToken();
94784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    return Type;
94884d0a19828599e8623223632d59447fd498999cfDouglas Gregor  }
94984d0a19828599e8623223632d59447fd498999cfDouglas Gregor
95042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // We have an identifier; check whether it is actually a type.
951c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain  IdentifierInfo *CorrectedII = 0;
952059101f922de6eb765601459925f4c8914420b23Douglas Gregor  ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true,
9539e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor                                        false, ParsedType(),
954fad03b75e0297546c5d12ec420b5b79d5b7baa2aAbramo Bagnara                                        /*IsCtorOrDtorName=*/false,
955c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain                                        /*NonTrivialTypeSourceInfo=*/true,
956c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain                                        &CorrectedII);
957193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  if (!Type) {
958124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor    Diag(IdLoc, diag::err_expected_class_name);
95931a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
96042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
96142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
96242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Consume the identifier.
96384d0a19828599e8623223632d59447fd498999cfDouglas Gregor  EndLocation = IdLoc;
9645606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
9655606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  // Fake up a Declarator to use with ActOnTypeName.
9660b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  DeclSpec DS(AttrFactory);
9675606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetRangeStart(IdLoc);
9685606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetRangeEnd(EndLocation);
969059101f922de6eb765601459925f4c8914420b23Douglas Gregor  DS.getTypeSpecScope() = SS;
9705606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
9715606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  const char *PrevSpec = 0;
9725606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  unsigned DiagID;
9735606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type);
9745606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
9755606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
9765606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
97742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor}
97842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
979c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallvoid Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {
980c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  while (Tok.is(tok::kw___single_inheritance) ||
981c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall         Tok.is(tok::kw___multiple_inheritance) ||
982c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall         Tok.is(tok::kw___virtual_inheritance)) {
983c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    IdentifierInfo *AttrName = Tok.getIdentifierInfo();
984c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    SourceLocation AttrNameLoc = ConsumeToken();
985c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
98693f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt                 SourceLocation(), 0, 0, AttributeList::AS_GNU);
987c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  }
988c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall}
989c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall
990c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// Determine whether the following tokens are valid after a type-specifier
991c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// which could be a standalone declaration. This will conservatively return
992c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// true if there's any doubt, and is appropriate for insert-';' fixits.
993139be7007eba3bd491ca50297888be507753a95dRichard Smithbool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
994c9f351700721150a985f21844fbfec55b04e861dRichard Smith  // This switch enumerates the valid "follow" set for type-specifiers.
995c9f351700721150a985f21844fbfec55b04e861dRichard Smith  switch (Tok.getKind()) {
996c9f351700721150a985f21844fbfec55b04e861dRichard Smith  default: break;
997c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::semi:               // struct foo {...} ;
998c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::star:               // struct foo {...} *         P;
999c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::amp:                // struct foo {...} &         R = ...
1000ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  case tok::ampamp:             // struct foo {...} &&        R = ...
1001c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::identifier:         // struct foo {...} V         ;
1002c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::r_paren:            //(struct foo {...} )         {4}
1003c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::annot_cxxscope:     // struct foo {...} a::       b;
1004c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::annot_typename:     // struct foo {...} a         ::b;
1005c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::annot_template_id:  // struct foo {...} a<int>    ::b;
1006c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::l_paren:            // struct foo {...} (         x);
1007c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::comma:              // __builtin_offsetof(struct foo{...} ,
1008ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  case tok::kw_operator:        // struct foo       operator  ++() {...}
1009c9f351700721150a985f21844fbfec55b04e861dRichard Smith    return true;
1010139be7007eba3bd491ca50297888be507753a95dRichard Smith  case tok::colon:
1011139be7007eba3bd491ca50297888be507753a95dRichard Smith    return CouldBeBitfield;     // enum E { ... }   :         2;
1012c9f351700721150a985f21844fbfec55b04e861dRichard Smith  // Type qualifiers
1013c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_const:           // struct foo {...} const     x;
1014c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_volatile:        // struct foo {...} volatile  x;
1015c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_restrict:        // struct foo {...} restrict  x;
1016ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  // Function specifiers
1017ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  // Note, no 'explicit'. An explicit function must be either a conversion
1018ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  // operator or a constructor. Either way, it can't have a return type.
1019ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  case tok::kw_inline:          // struct foo       inline    f();
1020ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  case tok::kw_virtual:         // struct foo       virtual   f();
1021ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  case tok::kw_friend:          // struct foo       friend    f();
1022c9f351700721150a985f21844fbfec55b04e861dRichard Smith  // Storage-class specifiers
1023c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_static:          // struct foo {...} static    x;
1024c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_extern:          // struct foo {...} extern    x;
1025c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_typedef:         // struct foo {...} typedef   x;
1026c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_register:        // struct foo {...} register  x;
1027c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_auto:            // struct foo {...} auto      x;
1028c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_mutable:         // struct foo {...} mutable   x;
1029ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  case tok::kw_thread_local:    // struct foo {...} thread_local x;
1030c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::kw_constexpr:       // struct foo {...} constexpr x;
1031c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // As shown above, type qualifiers and storage class specifiers absolutely
1032c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // can occur after class specifiers according to the grammar.  However,
1033c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // almost no one actually writes code like this.  If we see one of these,
1034c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // it is much more likely that someone missed a semi colon and the
1035c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // type/storage class specifier we're seeing is part of the *next*
1036c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // intended declaration, as in:
1037c9f351700721150a985f21844fbfec55b04e861dRichard Smith    //
1038c9f351700721150a985f21844fbfec55b04e861dRichard Smith    //   struct foo { ... }
1039c9f351700721150a985f21844fbfec55b04e861dRichard Smith    //   typedef int X;
1040c9f351700721150a985f21844fbfec55b04e861dRichard Smith    //
1041c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // We'd really like to emit a missing semicolon error instead of emitting
1042c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // an error on the 'int' saying that you can't have two type specifiers in
1043c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // the same declaration of X.  Because of this, we look ahead past this
1044c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // token to see if it's a type specifier.  If so, we know the code is
1045c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // otherwise invalid, so we can produce the expected semi error.
1046c9f351700721150a985f21844fbfec55b04e861dRichard Smith    if (!isKnownToBeTypeSpecifier(NextToken()))
1047c9f351700721150a985f21844fbfec55b04e861dRichard Smith      return true;
1048c9f351700721150a985f21844fbfec55b04e861dRichard Smith    break;
1049c9f351700721150a985f21844fbfec55b04e861dRichard Smith  case tok::r_brace:  // struct bar { struct foo {...} }
1050c9f351700721150a985f21844fbfec55b04e861dRichard Smith    // Missing ';' at end of struct is accepted as an extension in C mode.
1051c9f351700721150a985f21844fbfec55b04e861dRichard Smith    if (!getLangOpts().CPlusPlus)
1052c9f351700721150a985f21844fbfec55b04e861dRichard Smith      return true;
1053c9f351700721150a985f21844fbfec55b04e861dRichard Smith    break;
1054ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith    // C++11 attributes
1055ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith  case tok::l_square: // enum E [[]] x
1056ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith    // Note, no tok::kw_alignas here; alignas cannot appertain to a type.
1057ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith    return getLangOpts().CPlusPlus11 && NextToken().is(tok::l_square);
10588338a9d28c4a9d06b19b1c5df51e70182914e2dfRichard Smith  case tok::greater:
10598338a9d28c4a9d06b19b1c5df51e70182914e2dfRichard Smith    // template<class T = class X>
10608338a9d28c4a9d06b19b1c5df51e70182914e2dfRichard Smith    return getLangOpts().CPlusPlus;
1061c9f351700721150a985f21844fbfec55b04e861dRichard Smith  }
1062c9f351700721150a985f21844fbfec55b04e861dRichard Smith  return false;
1063c9f351700721150a985f21844fbfec55b04e861dRichard Smith}
1064c9f351700721150a985f21844fbfec55b04e861dRichard Smith
1065e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
1066e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
1067e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that
106869730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith/// cannot start a definition.
1069e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1070e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-specifier: [C++ class]
1071e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}'
1072e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}' attributes[opt]
1073e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-head:
1074e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key identifier[opt] base-clause[opt]
1075e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier identifier base-clause[opt]
1076e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier[opt] simple-template-id
1077e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          base-clause[opt]
1078e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   class-key attributes[opt] identifier[opt] base-clause[opt]
10791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier
1080e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          identifier base-clause[opt]
10811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier[opt]
1082e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          simple-template-id base-clause[opt]
1083e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-key:
1084e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'class'
1085e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
1086e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
1087e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1088e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       elaborated-type-specifier: [C++ dcl.type.elab]
10891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] identifier
10901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
10911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///                          simple-template-id
1092e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1093e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  Note that the C++ class-specifier and elaborated-type-specifier,
1094e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  together, subsume the C99 struct-or-union-specifier:
1095e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1096e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union-specifier: [C99 6.7.2.1]
1097e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier[opt] '{' struct-contents '}'
1098e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier
1099e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier[opt] '{' struct-contents
1100e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                                                         '}' attributes[opt]
1101e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier
1102e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union:
1103e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
1104e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
11054c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattnervoid Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
11064c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner                                 SourceLocation StartLoc, DeclSpec &DS,
11074d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                 const ParsedTemplateInfo &TemplateInfo,
1108efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor                                 AccessSpecifier AS,
11092e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han                                 bool EnteringContext, DeclSpecContext DSC,
1110ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling                                 ParsedAttributesWithRange &Attributes) {
111117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos  DeclSpec::TST TagType;
111217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos  if (TagTokKind == tok::kw_struct)
111317d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos    TagType = DeclSpec::TST_struct;
111417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos  else if (TagTokKind == tok::kw___interface)
111517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos    TagType = DeclSpec::TST_interface;
111617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos  else if (TagTokKind == tok::kw_class)
111717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos    TagType = DeclSpec::TST_class;
111817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos  else {
11194c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    assert(TagTokKind == tok::kw_union && "Not a class specifier");
11204c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_union;
11214c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  }
1122e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1123374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  if (Tok.is(tok::code_completion)) {
1124374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor    // Code completion for a struct, class, or union name.
112523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteTag(getCurScope(), TagType);
11267d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    return cutOffParsing();
1127374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  }
1128193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1129926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // C++03 [temp.explicit] 14.7.2/8:
1130926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //   The usual access checking rules do not apply to names used to specify
1131926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //   explicit instantiations.
1132926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //
1133926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // As an extension we do not perform access checking on the names used to
1134926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // specify explicit specializations either. This is important to allow
1135926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // specializing traits classes for private types.
113613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  //
113713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  // Note that we don't suppress if this turns out to be an elaborated
113813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  // type specifier.
113913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  bool shouldDelayDiagsInTag =
114013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
114113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall     TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
114213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);
1143926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
11442edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt  ParsedAttributesWithRange attrs(AttrFactory);
1145e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If attributes exist after tag, parse them.
1146e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw___attribute))
11477f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
1148e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1149f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff  // If declspecs exist after tag, parse them.
1150b1d397c23e1f8fd8b404d5731d531e7500f7140dJohn McCall  while (Tok.is(tok::kw___declspec))
11517f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseMicrosoftDeclSpec(attrs);
1152193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1153c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  // Parse inheritance specifiers.
1154c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall  if (Tok.is(tok::kw___single_inheritance) ||
1155c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      Tok.is(tok::kw___multiple_inheritance) ||
1156c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      Tok.is(tok::kw___virtual_inheritance))
1157c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall      ParseMicrosoftInheritanceClassAttributes(attrs);
1158c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall
1159bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // If C++0x attributes exist here, parse them.
1160bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Are we consistent with the ordering of parsing of different
1161bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // styles of attributes?
11624e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith  MaybeParseCXX11Attributes(attrs);
11631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
116407fc1ba7553f2f5bf26984091197311decd9028eMichael Han  // Source location used by FIXIT to insert misplaced
116507fc1ba7553f2f5bf26984091197311decd9028eMichael Han  // C++11 attributes
116607fc1ba7553f2f5bf26984091197311decd9028eMichael Han  SourceLocation AttrFixitLoc = Tok.getLocation();
116707fc1ba7553f2f5bf26984091197311decd9028eMichael Han
116820c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley  if (TagType == DeclSpec::TST_struct &&
1169b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      !Tok.is(tok::identifier) &&
1170b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      Tok.getIdentifierInfo() &&
1171b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      (Tok.is(tok::kw___is_arithmetic) ||
1172b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_convertible) ||
117320c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley       Tok.is(tok::kw___is_empty) ||
1174b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_floating_point) ||
1175b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_function) ||
117620c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley       Tok.is(tok::kw___is_fundamental) ||
1177b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_integral) ||
1178b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_member_function_pointer) ||
1179b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_member_pointer) ||
1180b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_pod) ||
1181b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_pointer) ||
1182b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_same) ||
1183877222e2491bbc40a5c74cc100c540983f306b70Douglas Gregor       Tok.is(tok::kw___is_scalar) ||
1184b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_signed) ||
1185b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_unsigned) ||
1186b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_void))) {
1187688761409155b47c39eb5dae1b8c6c8a9f43307aDouglas Gregor    // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the
1188b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // name of struct templates, but some are keywords in GCC >= 4.3
1189b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // and Clang. Therefore, when we see the token sequence "struct
1190b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // X", make X into a normal identifier rather than a keyword, to
1191b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // allow libstdc++ 4.2 and libc++ to work properly.
1192646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
1193b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.setKind(tok::identifier);
1194b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  }
11951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1196eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse the (optional) nested-name-specifier.
1197aa87d33309f505b68c3bfc17486c93e4d224b24fJohn McCall  CXXScopeSpec &SS = DS.getTypeSpecScope();
11984e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().CPlusPlus) {
119908d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    // "FOO : BAR" is not a potential typo for "FOO::BAR".
120008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    ColonProtectionRAIIObject X(*this);
1201193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1202efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor    if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext))
1203207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      DS.SetTypeSpecError();
12049ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall    if (SS.isSet())
120508d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner      if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
120608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner        Diag(Tok, diag::err_expected_ident);
120708d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  }
1208cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
12092cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor  TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
12102cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor
1211cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  // Parse the (optional) class name or simple-template-id.
1212e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  IdentifierInfo *Name = 0;
1213e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation NameLoc;
121439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  TemplateIdAnnotation *TemplateId = 0;
1215e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::identifier)) {
1216e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    Name = Tok.getIdentifierInfo();
1217e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    NameLoc = ConsumeToken();
1218193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
12194e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (Tok.is(tok::less) && getLangOpts().CPlusPlus) {
1220193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      // The name was supposed to refer to a template, but didn't.
12212cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // Eat the template argument list and try to continue parsing this as
12222cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // a class (or template thereof).
12232cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      TemplateArgList TemplateArgs;
12242cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      SourceLocation LAngleLoc, RAngleLoc;
1225059101f922de6eb765601459925f4c8914420b23Douglas Gregor      if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, SS,
12262cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor                                           true, LAngleLoc,
1227314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor                                           TemplateArgs, RAngleLoc)) {
12282cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // We couldn't parse the template argument list at all, so don't
12292cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // try to give any location information for the list.
12302cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        LAngleLoc = RAngleLoc = SourceLocation();
12312cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
1232193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
12332cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      Diag(NameLoc, diag::err_explicit_spec_non_template)
123417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos        << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
123517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos        << (TagType == DeclSpec::TST_class? 0
123617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos            : TagType == DeclSpec::TST_struct? 1
123717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos            : TagType == DeclSpec::TST_interface? 2
123817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos            : 3)
123917d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos        << Name
124017d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos        << SourceRange(LAngleLoc, RAngleLoc);
124117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos
1242193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      // Strip off the last template parameter list if it was empty, since
1243c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      // we've removed its template argument list.
1244c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
1245c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        if (TemplateParams && TemplateParams->size() > 1) {
1246c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams->pop_back();
1247c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        } else {
1248c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams = 0;
1249193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam          const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
1250c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor            = ParsedTemplateInfo::NonTemplate;
1251c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        }
1252c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      } else if (TemplateInfo.Kind
1253c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor                                == ParsedTemplateInfo::ExplicitInstantiation) {
1254c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        // Pretend this is just a forward declaration.
12552cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        TemplateParams = 0;
1256193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam        const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
12572cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor          = ParsedTemplateInfo::NonTemplate;
1258193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam        const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc
1259c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
1260c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc
1261c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
12622cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
12632cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor    }
126439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  } else if (Tok.is(tok::annot_template_id)) {
126525a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis    TemplateId = takeTemplateIdAnnotation(Tok);
126639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    NameLoc = ConsumeToken();
1267cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
1268059101f922de6eb765601459925f4c8914420b23Douglas Gregor    if (TemplateId->Kind != TNK_Type_template &&
1269059101f922de6eb765601459925f4c8914420b23Douglas Gregor        TemplateId->Kind != TNK_Dependent_template_name) {
127039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // The template-name in the simple-template-id refers to
127139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // something other than a class template. Give an appropriate
127239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // error message and skip to the ';'.
127339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SourceRange Range(NameLoc);
127439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      if (SS.isNotEmpty())
127539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        Range.setBegin(SS.getBeginLoc());
127639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
127739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
12786e91f4bd9a05ca2c58ba11d541d8f9dab5514b76Richard Trieu        << TemplateId->Name << static_cast<int>(TemplateId->Kind) << Range;
12791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
128039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      DS.SetTypeSpecError();
128139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SkipUntil(tok::semi, false, true);
128239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      return;
1283cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    }
1284e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1285e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
12867796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  // There are four options here.
12877796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //  - If we are in a trailing return type, this is always just a reference,
12887796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //    and we must not try to parse a definition. For instance,
12897796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //      [] () -> struct S { };
12907796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //    does not define a type.
12917796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //  - If we have 'struct foo {...', 'struct foo :...',
12927796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //    'struct foo final :' or 'struct foo final {', then this is a definition.
12937796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //  - If we have 'struct foo;', then this is either a forward declaration
12947796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //    or a friend declaration, which have to be treated differently.
12957796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  //  - Otherwise we have something like 'struct foo xyz', a reference.
12962e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //
12972e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //  We also detect these erroneous cases to provide better diagnostic for
12982e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //  C++11 attributes parsing.
12992e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //  - attributes follow class name:
13002e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //    struct foo [[]] {};
13012e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //  - attributes appear before or after 'final':
13022e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //    struct foo [[]] final [[]] {};
13032e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  //
130469730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  // However, in type-specifier-seq's, things look like declarations but are
130569730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  // just references, e.g.
130669730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  //   new struct s;
1307d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // or
130869730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  //   &T::operator struct s;
130969730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith  // For these, DSC is DSC_type_specifier.
13102e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
13112e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  // If there are attributes after class name, parse them.
13124e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith  MaybeParseCXX11Attributes(Attributes);
13132e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
1314f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  Sema::TagUseKind TUK;
13157796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  if (DSC == DSC_trailing)
13167796eb5643244f3134834253ce5ea89107ac21c1Richard Smith    TUK = Sema::TUK_Reference;
13177796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  else if (Tok.is(tok::l_brace) ||
13187796eb5643244f3134834253ce5ea89107ac21c1Richard Smith           (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
13194e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith           (isCXX11FinalKeyword() &&
13206f42669b7c0b81b07a15a0483aa5e897ce57cb45David Blaikie            (NextToken().is(tok::l_brace) || NextToken().is(tok::colon)))) {
1321d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    if (DS.isFriendSpecified()) {
1322d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // C++ [class.friend]p2:
1323d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      //   A class shall not be defined in a friend declaration.
1324bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith      Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
1325d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor        << SourceRange(DS.getFriendSpecLoc());
1326d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor
1327d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Skip everything up to the semicolon, so that this looks like a proper
1328d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // friend class (or template thereof) declaration.
1329d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      SkipUntil(tok::semi, true, true);
1330f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall      TUK = Sema::TUK_Friend;
1331d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    } else {
1332d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Okay, this is a class definition.
1333f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall      TUK = Sema::TUK_Definition;
1334d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    }
1335150d853343758281f7b0c44e058ea81da45b79beRichard Smith  } else if (isCXX11FinalKeyword() && (NextToken().is(tok::l_square) ||
1336150d853343758281f7b0c44e058ea81da45b79beRichard Smith                                       NextToken().is(tok::kw_alignas))) {
13372e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    // We can't tell if this is a definition or reference
13382e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    // until we skipped the 'final' and C++11 attribute specifiers.
13392e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    TentativeParsingAction PA(*this);
13402e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
13412e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    // Skip the 'final' keyword.
13422e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    ConsumeToken();
13432e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
13442e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    // Skip C++11 attribute specifiers.
13452e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    while (true) {
13462e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han      if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {
13472e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han        ConsumeBracket();
13482e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han        if (!SkipUntil(tok::r_square))
13492e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han          break;
1350150d853343758281f7b0c44e058ea81da45b79beRichard Smith      } else if (Tok.is(tok::kw_alignas) && NextToken().is(tok::l_paren)) {
13512e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han        ConsumeToken();
13522e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han        ConsumeParen();
13532e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han        if (!SkipUntil(tok::r_paren))
13542e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han          break;
13552e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han      } else {
13562e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han        break;
13572e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han      }
13582e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    }
13592e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
13602e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    if (Tok.is(tok::l_brace) || Tok.is(tok::colon))
13612e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han      TUK = Sema::TUK_Definition;
13622e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    else
13632e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han      TUK = Sema::TUK_Reference;
13642e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
13652e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han    PA.Revert();
1366c9f351700721150a985f21844fbfec55b04e861dRichard Smith  } else if (DSC != DSC_type_specifier &&
1367c9f351700721150a985f21844fbfec55b04e861dRichard Smith             (Tok.is(tok::semi) ||
1368139be7007eba3bd491ca50297888be507753a95dRichard Smith              (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) {
1369f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
137017d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos    if (Tok.isNot(tok::semi)) {
137117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos      // A semicolon was missing after this declaration. Diagnose and recover.
137217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
137317d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos        DeclSpec::getSpecifierName(TagType));
137417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos      PP.EnterToken(Tok);
137517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos      Tok.setKind(tok::semi);
137617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos    }
1377c9f351700721150a985f21844fbfec55b04e861dRichard Smith  } else
1378f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = Sema::TUK_Reference;
1379e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
13802e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  // Forbid misplaced attributes. In cases of a reference, we pass attributes
13812e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han  // to caller to handle.
138207fc1ba7553f2f5bf26984091197311decd9028eMichael Han  if (TUK != Sema::TUK_Reference) {
138307fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // If this is not a reference, then the only possible
138407fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // valid place for C++11 attributes to appear here
138507fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // is between class-key and class-name. If there are
138607fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // any attributes after class-name, we try a fixit to move
138707fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // them to the right place.
138807fc1ba7553f2f5bf26984091197311decd9028eMichael Han    SourceRange AttrRange = Attributes.Range;
138907fc1ba7553f2f5bf26984091197311decd9028eMichael Han    if (AttrRange.isValid()) {
139007fc1ba7553f2f5bf26984091197311decd9028eMichael Han      Diag(AttrRange.getBegin(), diag::err_attributes_not_allowed)
139107fc1ba7553f2f5bf26984091197311decd9028eMichael Han        << AttrRange
139207fc1ba7553f2f5bf26984091197311decd9028eMichael Han        << FixItHint::CreateInsertionFromRange(AttrFixitLoc,
139307fc1ba7553f2f5bf26984091197311decd9028eMichael Han                                               CharSourceRange(AttrRange, true))
139407fc1ba7553f2f5bf26984091197311decd9028eMichael Han        << FixItHint::CreateRemoval(AttrRange);
139507fc1ba7553f2f5bf26984091197311decd9028eMichael Han
139607fc1ba7553f2f5bf26984091197311decd9028eMichael Han      // Recover by adding misplaced attributes to the attribute list
139707fc1ba7553f2f5bf26984091197311decd9028eMichael Han      // of the class so they can be applied on the class later.
139807fc1ba7553f2f5bf26984091197311decd9028eMichael Han      attrs.takeAllFrom(Attributes);
139907fc1ba7553f2f5bf26984091197311decd9028eMichael Han    }
140007fc1ba7553f2f5bf26984091197311decd9028eMichael Han  }
14012e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
140213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  // If this is an elaborated type specifier, and we delayed
140313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  // diagnostics before, just merge them into the current pool.
140413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  if (shouldDelayDiagsInTag) {
140513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    diagsFromTag.done();
140613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall    if (TUK == Sema::TUK_Reference)
140713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall      diagsFromTag.redelay();
140813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall  }
140913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall
1410207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall  if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error ||
1411f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                               TUK != Sema::TUK_Definition)) {
1412207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall    if (DS.getTypeSpecType() != DeclSpec::TST_error) {
1413207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      // We have a declaration or reference to an anonymous class.
1414207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      Diag(StartLoc, diag::err_anon_type_definition)
1415207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall        << DeclSpec::getSpecifierName(TagType);
1416207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall    }
1417e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1418e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SkipUntil(tok::comma, true);
1419e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    return;
1420e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1421e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1422ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  // Create the tag portion of the class or class template.
1423d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  DeclResult TagOrTempResult = true; // invalid
1424d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  TypeResult TypeResult = true; // invalid
14254d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
1426402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor  bool Owned = false;
1427f1bbbb49f06a7462476cd88166fccda5feb15cabJohn McCall  if (TemplateId) {
14284d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // Explicit specialization, class template partial specialization,
14294d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // or explicit instantiation.
14305354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer    ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
143139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->NumArgs);
14324d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1433f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        TUK == Sema::TUK_Declaration) {
14344d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit instantiation of a class template.
14352edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt      ProhibitAttributes(attrs);
14362edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
14374d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
143823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        = Actions.ActOnExplicitInstantiation(getCurScope(),
143945f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                             TemplateInfo.ExternLoc,
14401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateInfo.TemplateLoc,
14414d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TagType,
14421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             StartLoc,
14434d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             SS,
14442b5289b6fd7e3d9899868410a498c081c9595662John McCall                                             TemplateId->Template,
14451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->TemplateNameLoc,
14461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->LAngleLoc,
14474d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateArgsPtr,
14481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->RAngleLoc,
14497f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                             attrs.getList());
145074256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall
145174256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // Friend template-ids are treated as references unless
145274256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // they have template headers, in which case they're ill-formed
145374256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // (FIXME: "template <class T> friend class A<T>::B<int>;").
145474256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // We diagnose this error in ActOnClassTemplateSpecialization.
1455f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    } else if (TUK == Sema::TUK_Reference ||
1456f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall               (TUK == Sema::TUK_Friend &&
145774256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall                TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
14582edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt      ProhibitAttributes(attrs);
145955d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara      TypeResult = Actions.ActOnTagTemplateIdType(TUK, TagType, StartLoc,
1460059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->SS,
146155d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara                                                  TemplateId->TemplateKWLoc,
1462059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->Template,
1463059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->TemplateNameLoc,
1464059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->LAngleLoc,
1465059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateArgsPtr,
146655d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara                                                  TemplateId->RAngleLoc);
14674d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    } else {
14684d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit specialization or a class template
14694d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // partial specialization.
14704d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TemplateParameterLists FakedParamLists;
14714d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
14724d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // This looks like an explicit instantiation, because we have
14734d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // something like
14744d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
14754d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //   template class Foo<X>
14764d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
14773f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor        // but it actually has a definition. Most likely, this was
14784d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // meant to be an explicit specialization, but the user forgot
14794d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // the '<>' after 'template'.
14804985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	// It this is friend declaration however, since it cannot have a
14814985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	// template header, it is most likely that the user meant to
14824985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	// remove the 'template' keyword.
14834985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo        assert((TUK == Sema::TUK_Definition || TUK == Sema::TUK_Friend) &&
14844985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	       "Expected a definition here");
14854985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo
14864985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	if (TUK == Sema::TUK_Friend) {
14874985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	  Diag(DS.getFriendSpecLoc(),
14884985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	       diag::err_friend_explicit_instantiation);
14894985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	  TemplateParams = 0;
14904985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	} else {
14914985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	  SourceLocation LAngleLoc
14924985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	    = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
14934985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	  Diag(TemplateId->TemplateNameLoc,
14944985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	       diag::err_explicit_instantiation_with_definition)
14954985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	    << SourceRange(TemplateInfo.TemplateLoc)
14964985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	    << FixItHint::CreateInsertion(LAngleLoc, "<>");
14974985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo
14984985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	  // Create a fake template parameter list that contains only
14994985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	  // "template<>", so that we treat this construct as a class
15004985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	  // template specialization.
15014985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	  FakedParamLists.push_back(
15024985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	    Actions.ActOnTemplateParameterList(0, SourceLocation(),
15034985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo					       TemplateInfo.TemplateLoc,
15044985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo					       LAngleLoc,
15054985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo					       0, 0,
15064985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo					       LAngleLoc));
15074985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	  TemplateParams = &FakedParamLists;
15084985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo	}
15094d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      }
15104d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
15114d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // Build the class template specialization.
15124d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
151323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK,
1514d023aec8907831a18d3514a95b843a7ee06b6b5eDouglas Gregor                       StartLoc, DS.getModulePrivateSpecLoc(), SS,
15152b5289b6fd7e3d9899868410a498c081c9595662John McCall                       TemplateId->Template,
15161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->TemplateNameLoc,
15171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->LAngleLoc,
151839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       TemplateArgsPtr,
15191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->RAngleLoc,
15207f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                       attrs.getList(),
15215354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer                       MultiTemplateParamsArg(
1522cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                    TemplateParams? &(*TemplateParams)[0] : 0,
1523cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                 TemplateParams? TemplateParams->size() : 0));
15244d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    }
15253f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1526f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall             TUK == Sema::TUK_Declaration) {
15273f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Explicit instantiation of a member of a class template
15283f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // specialization, e.g.,
15293f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
15303f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //   template struct Outer<int>::Inner;
15313f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
15322edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt    ProhibitAttributes(attrs);
15332edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
15343f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    TagOrTempResult
153523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      = Actions.ActOnExplicitInstantiation(getCurScope(),
153645f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                           TemplateInfo.ExternLoc,
15371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TemplateInfo.TemplateLoc,
15381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TagType, StartLoc, SS, Name,
15397f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                           NameLoc, attrs.getList());
15409a34edb710917798aa30263374f624f13b594605John McCall  } else if (TUK == Sema::TUK_Friend &&
15419a34edb710917798aa30263374f624f13b594605John McCall             TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
15422edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt    ProhibitAttributes(attrs);
15432edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
15449a34edb710917798aa30263374f624f13b594605John McCall    TagOrTempResult =
15459a34edb710917798aa30263374f624f13b594605John McCall      Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(),
15469a34edb710917798aa30263374f624f13b594605John McCall                                      TagType, StartLoc, SS,
15477f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                      Name, NameLoc, attrs.getList(),
15485354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer                                      MultiTemplateParamsArg(
15499a34edb710917798aa30263374f624f13b594605John McCall                                    TemplateParams? &(*TemplateParams)[0] : 0,
15509a34edb710917798aa30263374f624f13b594605John McCall                                 TemplateParams? TemplateParams->size() : 0));
15513f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else {
15522edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt    if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition)
15532edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt      ProhibitAttributes(attrs);
15547c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo
15557c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo    if (TUK == Sema::TUK_Definition &&
15567c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo        TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
15577c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo      // If the declarator-id is not a template-id, issue a diagnostic and
15587c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo      // recover by ignoring the 'template' keyword.
15597c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo      Diag(Tok, diag::err_template_defn_explicit_instantiation)
15607c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo        << 1 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc);
15614985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo      TemplateParams = 0;
15627c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo    }
15632edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt
1564c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    bool IsDependent = false;
1565c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
1566a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    // Don't pass down template parameter lists if this is just a tag
1567a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    // reference.  For example, we don't need the template parameters here:
1568a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    //   template <class T> class A *makeA(T t);
1569a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    MultiTemplateParamsArg TParams;
1570a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    if (TUK != Sema::TUK_Reference && TemplateParams)
1571a25c4080a490ea2bab6f54094dd75b19eae83770John McCall      TParams =
1572a25c4080a490ea2bab6f54094dd75b19eae83770John McCall        MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size());
1573a25c4080a490ea2bab6f54094dd75b19eae83770John McCall
15743f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Declaration or definition of a class type
15759a34edb710917798aa30263374f624f13b594605John McCall    TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc,
15767f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                       SS, Name, NameLoc, attrs.getList(), AS,
1577e761230ae3751b525cadd8066c74ec278ee4ef57Douglas Gregor                                       DS.getModulePrivateSpecLoc(),
1578bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith                                       TParams, Owned, IsDependent,
1579bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith                                       SourceLocation(), false,
1580bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith                                       clang::TypeResult());
1581c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
1582c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // If ActOnTag said the type was dependent, try again with the
1583c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // less common call.
15849a34edb710917798aa30263374f624f13b594605John McCall    if (IsDependent) {
15859a34edb710917798aa30263374f624f13b594605John McCall      assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend);
158623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK,
1587193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                                             SS, Name, StartLoc, NameLoc);
15889a34edb710917798aa30263374f624f13b594605John McCall    }
15893f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  }
1590e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1591e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If there is a body, parse it and inform the actions module.
1592f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  if (TUK == Sema::TUK_Definition) {
1593bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    assert(Tok.is(tok::l_brace) ||
15944e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie           (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
15954e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith           isCXX11FinalKeyword());
15964e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().CPlusPlus)
159707fc1ba7553f2f5bf26984091197311decd9028eMichael Han      ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs, TagType,
159807fc1ba7553f2f5bf26984091197311decd9028eMichael Han                                  TagOrTempResult.get());
159907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    else
1600212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
1601e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1602e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1603b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  const char *PrevSpec = 0;
1604b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  unsigned DiagID;
1605b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  bool Result;
1606c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  if (!TypeResult.isInvalid()) {
16070daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara    Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
16080daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                NameLoc.isValid() ? NameLoc : StartLoc,
1609b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                PrevSpec, DiagID, TypeResult.get());
1610c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else if (!TagOrTempResult.isInvalid()) {
16110daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara    Result = DS.SetTypeSpecType(TagType, StartLoc,
16120daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                NameLoc.isValid() ? NameLoc : StartLoc,
16130daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                PrevSpec, DiagID, TagOrTempResult.get(), Owned);
1614c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else {
1615ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    DS.SetTypeSpecError();
161666e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson    return;
161766e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson  }
16181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1619b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  if (Result)
1620fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
1621193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
16224ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // At this point, we've successfully parsed a class-specifier in 'definition'
16234ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // form (e.g. "struct foo { int x; }".  While we could just return here, we're
16244ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // going to look at what comes after it to improve error recovery.  If an
16254ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // impossible token occurs next, we assume that the programmer forgot a ; at
16264ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // the end of the declaration and recover that way.
16274ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  //
1628c9f351700721150a985f21844fbfec55b04e861dRichard Smith  // Also enforce C++ [temp]p3:
1629c9f351700721150a985f21844fbfec55b04e861dRichard Smith  //   In a template-declaration which defines a class, no declarator
1630c9f351700721150a985f21844fbfec55b04e861dRichard Smith  //   is permitted.
163117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos  if (TUK == Sema::TUK_Definition &&
163217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos      (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) {
16337d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis    if (Tok.isNot(tok::semi)) {
16347d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
16357d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis        DeclSpec::getSpecifierName(TagType));
16367d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis      // Push this token back into the preprocessor and change our current token
16377d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis      // to ';' so that the rest of the code recovers as though there were an
16387d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis      // ';' after the definition.
16397d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis      PP.EnterToken(Tok);
16407d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis      Tok.setKind(tok::semi);
16417d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis    }
16424ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  }
1643e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1644e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
16451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
1646e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1647e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-clause : [C++ class.derived]
1648e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ':' base-specifier-list
1649e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier-list:
1650e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier '...'[opt]
1651e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier-list ',' base-specifier '...'[opt]
1652d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseBaseClause(Decl *ClassDecl) {
1653e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  assert(Tok.is(tok::colon) && "Not a base clause");
1654e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  ConsumeToken();
1655e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1656f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Build up an array of parsed base specifiers.
16575f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<CXXBaseSpecifier *, 8> BaseInfo;
1658f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
1659e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  while (true) {
1660e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Parse a base-specifier.
1661f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    BaseResult Result = ParseBaseSpecifier(ClassDecl);
16625ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor    if (Result.isInvalid()) {
1663e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Skip the rest of this base specifier, up until the comma or
1664e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // opening brace.
1665f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      SkipUntil(tok::comma, tok::l_brace, true, true);
1666f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    } else {
1667f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      // Add this to our array of base specifiers.
16685ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor      BaseInfo.push_back(Result.get());
1669e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
1670e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1671e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // If the next token is a comma, consume it and keep reading
1672e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // base-specifiers.
1673e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (Tok.isNot(tok::comma)) break;
16741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1675e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Consume the comma.
1676e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
1677e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1678f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
1679f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Attach the base specifiers
1680beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad  Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size());
1681e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1682e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1683e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
1684e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example:
1685e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///    class foo : public bar, virtual private baz {
1686e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers.
1687e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1688e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier: [C++ class.derived]
1689053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///         attribute-specifier-seq[opt] base-type-specifier
1690053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///         attribute-specifier-seq[opt] 'virtual' access-specifier[opt]
1691053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///                 base-type-specifier
1692053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///         attribute-specifier-seq[opt] access-specifier 'virtual'[opt]
1693053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith///                 base-type-specifier
1694d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {
1695e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  bool IsVirtual = false;
1696e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation StartLoc = Tok.getLocation();
1697e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1698053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith  ParsedAttributesWithRange Attributes(AttrFactory);
1699053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith  MaybeParseCXX11Attributes(Attributes);
1700053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith
1701e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword.
1702e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
1703e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
1704e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
1705e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1706e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1707053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith  CheckMisplacedCXX11Attribute(Attributes, StartLoc);
1708053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith
1709e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse an (optional) access specifier.
1710e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  AccessSpecifier Access = getAccessSpecifierIfPresent();
171192f883177b162928a8e632e4e3b93fafd2b26072John McCall  if (Access != AS_none)
1712e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
17131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1714053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith  CheckMisplacedCXX11Attribute(Attributes, StartLoc);
1715053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith
1716e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword (again!), in case it came after the
1717e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // access specifier.
1718e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
1719e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SourceLocation VirtualLoc = ConsumeToken();
1720e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (IsVirtual) {
1721e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Complain about duplicate 'virtual'
17221ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner      Diag(VirtualLoc, diag::err_dup_virtual)
1723849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor        << FixItHint::CreateRemoval(VirtualLoc);
1724e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
1725e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1726e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
1727e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1728e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1729053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith  CheckMisplacedCXX11Attribute(Attributes, StartLoc);
1730053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith
173142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Parse the class-name.
17327f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceLocation EndLocation;
173322216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie  SourceLocation BaseLoc;
173422216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie  TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation);
173531a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor  if (BaseType.isInvalid())
173642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor    return true;
17371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1738f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // Parse the optional ellipsis (for a pack expansion). The ellipsis is
1739f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // actually part of the base-specifier-list grammar productions, but we
1740f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // parse it here for convenience.
1741f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  SourceLocation EllipsisLoc;
1742f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  if (Tok.is(tok::ellipsis))
1743f90b27ad077c3339b62befc892382845339f9490Douglas Gregor    EllipsisLoc = ConsumeToken();
1744f90b27ad077c3339b62befc892382845339f9490Douglas Gregor
17451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Find the complete source range for the base-specifier.
17467f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceRange Range(StartLoc, EndLocation);
17471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1748e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Notify semantic analysis that we have parsed a complete
1749e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // base-specifier.
1750053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith  return Actions.ActOnBaseSpecifier(ClassDecl, Range, Attributes, IsVirtual,
1751053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith                                    Access, BaseType.get(), BaseLoc,
1752053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith                                    EllipsisLoc);
1753e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1754e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1755e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is
1756e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier.
1757e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1758e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       access-specifier: [C++ class.derived]
1759e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'private'
1760e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'protected'
1761e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'public'
17621eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAccessSpecifier Parser::getAccessSpecifierIfPresent() const {
1763e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  switch (Tok.getKind()) {
1764e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  default: return AS_none;
1765e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_private: return AS_private;
1766e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_protected: return AS_protected;
1767e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_public: return AS_public;
1768e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1769e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
17704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
177174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor/// \brief If the given declarator has any parts for which parsing has to be
1772a058fd4f0a944174295f77169b438510dad389f8Richard Smith/// delayed, e.g., default arguments, create a late-parsed method declaration
1773a058fd4f0a944174295f77169b438510dad389f8Richard Smith/// record to handle the parsing at the end of the class definition.
177474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregorvoid Parser::HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
177574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                                            Decl *ThisDecl) {
1776d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // We just declared a member function. If this member function
1777a058fd4f0a944174295f77169b438510dad389f8Richard Smith  // has any default arguments, we'll need to parse them later.
1778d33133cdc1af466f9c276249b2621be03867888bEli Friedman  LateParsedMethodDeclaration *LateMethod = 0;
17791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  DeclaratorChunk::FunctionTypeInfo &FTI
1780075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara    = DeclaratorInfo.getFunctionTypeInfo();
178174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
1782d33133cdc1af466f9c276249b2621be03867888bEli Friedman  for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
1783d33133cdc1af466f9c276249b2621be03867888bEli Friedman    if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
1784d33133cdc1af466f9c276249b2621be03867888bEli Friedman      if (!LateMethod) {
1785d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Push this method onto the stack of late-parsed method
1786d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // declarations.
1787d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
1788d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
178923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        LateMethod->TemplateScope = getCurScope()->isTemplateParamScope();
1790d33133cdc1af466f9c276249b2621be03867888bEli Friedman
1791d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Add all of the parameters prior to this one (they don't
1792d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // have default arguments).
1793d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateMethod->DefaultArgs.reserve(FTI.NumArgs);
1794d33133cdc1af466f9c276249b2621be03867888bEli Friedman        for (unsigned I = 0; I < ParamIdx; ++I)
1795d33133cdc1af466f9c276249b2621be03867888bEli Friedman          LateMethod->DefaultArgs.push_back(
17968f8210c47797f013e0fb24a26f9c4751b10783feDouglas Gregor                             LateParsedDefaultArgument(FTI.ArgInfo[I].Param));
1797d33133cdc1af466f9c276249b2621be03867888bEli Friedman      }
1798d33133cdc1af466f9c276249b2621be03867888bEli Friedman
179974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      // Add this parameter to the list of parameters (it may or may
1800d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // not have a default argument).
1801d33133cdc1af466f9c276249b2621be03867888bEli Friedman      LateMethod->DefaultArgs.push_back(
1802d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
1803d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                  FTI.ArgInfo[ParamIdx].DefaultArgTokens));
1804d33133cdc1af466f9c276249b2621be03867888bEli Friedman    }
1805d33133cdc1af466f9c276249b2621be03867888bEli Friedman  }
1806d33133cdc1af466f9c276249b2621be03867888bEli Friedman}
1807d33133cdc1af466f9c276249b2621be03867888bEli Friedman
18084e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith/// isCXX11VirtSpecifier - Determine whether the given token is a C++11
18091f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier.
18101f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
18111f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier:
18121f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         override
18131f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         final
18144e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard SmithVirtSpecifiers::Specifier Parser::isCXX11VirtSpecifier(const Token &Tok) const {
18154e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!getLangOpts().CPlusPlus)
1816cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson    return VirtSpecifiers::VS_None;
1817cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
1818b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  if (Tok.is(tok::identifier)) {
1819b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    IdentifierInfo *II = Tok.getIdentifierInfo();
18201f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
18217eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    // Initialize the contextual keywords.
18227eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    if (!Ident_final) {
18237eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson      Ident_final = &PP.getIdentifierTable().get("final");
18247eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson      Ident_override = &PP.getIdentifierTable().get("override");
18257eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    }
18267eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson
1827b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (II == Ident_override)
1828b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return VirtSpecifiers::VS_Override;
18291f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
1830b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (II == Ident_final)
1831b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return VirtSpecifiers::VS_Final;
1832b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  }
1833b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
1834b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  return VirtSpecifiers::VS_None;
18351f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson}
18361f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
18374e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith/// ParseOptionalCXX11VirtSpecifierSeq - Parse a virt-specifier-seq.
18381f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
18391f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier-seq:
18401f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier
18411f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier-seq virt-specifier
18424e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smithvoid Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS,
1843e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall                                                bool IsInterface) {
1844b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  while (true) {
18454e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith    VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier();
1846b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (Specifier == VirtSpecifiers::VS_None)
1847b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return;
1848b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
1849b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    // C++ [class.mem]p8:
1850b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    //   A virt-specifier-seq shall contain at most one of each virt-specifier.
1851cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson    const char *PrevSpec = 0;
185246127a96b6dd6b93aa18d5f7a55bc2db8b52a2c9Anders Carlsson    if (VS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec))
1853b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier)
1854b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson        << PrevSpec
1855b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson        << FixItHint::CreateRemoval(Tok.getLocation());
1856b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
1857e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall    if (IsInterface && Specifier == VirtSpecifiers::VS_Final) {
1858e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall      Diag(Tok.getLocation(), diag::err_override_control_interface)
1859e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        << VirtSpecifiers::getSpecifierName(Specifier);
1860e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall    } else {
186180ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith      Diag(Tok.getLocation(), getLangOpts().CPlusPlus11 ?
1862e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall           diag::warn_cxx98_compat_override_control_keyword :
1863e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall           diag::ext_override_control_keyword)
1864e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        << VirtSpecifiers::getSpecifierName(Specifier);
1865e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall    }
1866b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    ConsumeToken();
1867b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  }
18681f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson}
18691f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
18704e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith/// isCXX11FinalKeyword - Determine whether the next token is a C++11
18718a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson/// contextual 'final' keyword.
18724e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smithbool Parser::isCXX11FinalKeyword() const {
18734e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (!getLangOpts().CPlusPlus)
18748a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    return false;
1875cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
18768a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  if (!Tok.is(tok::identifier))
18778a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    return false;
1878cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
18798a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  // Initialize the contextual keywords.
18808a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  if (!Ident_final) {
18818a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    Ident_final = &PP.getIdentifierTable().get("final");
18828a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    Ident_override = &PP.getIdentifierTable().get("override");
1883cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson  }
18848a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson
18858a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  return Tok.getIdentifierInfo() == Ident_final;
1886cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson}
1887cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
18884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
18894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
18904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declaration:
18914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         decl-specifier-seq[opt] member-declarator-list[opt] ';'
18924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         function-definition ';'[opt]
18934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
18944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         using-declaration                                            [TODO]
1895511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration
18965aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson///         template-declaration
1897bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU]   '__extension__' member-declaration
18984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
18994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator-list:
19004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator
19014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator-list ',' member-declarator
19024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
19034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator:
19041f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         declarator virt-specifier-seq[opt] pure-specifier[opt]
19054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         declarator constant-initializer[opt]
19067a614d8380297fcd2bc23986241905d97222948cRichard Smith/// [C++11] declarator brace-or-equal-initializer[opt]
19074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         identifier[opt] ':' constant-expression
19084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
19091f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier-seq:
19101f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier
19111f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier-seq virt-specifier
19121f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
19131f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier:
19141f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         override
19151f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         final
19161f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
1917e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl///       pure-specifier:
19184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '= 0'
19194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
19204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       constant-initializer:
19214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '=' constant-expression
19224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
192337b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregorvoid Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
19245f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                            AttributeList *AccessAttrs,
1925c9068d7dd94d439cec66c421115d15303e481025John McCall                                       const ParsedTemplateInfo &TemplateInfo,
1926c9068d7dd94d439cec66c421115d15303e481025John McCall                                       ParsingDeclRAIIObject *TemplateDiags) {
19278a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor  if (Tok.is(tok::at)) {
19284e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().ObjC1 && NextToken().isObjCAtKeyword(tok::objc_defs))
19298a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor      Diag(Tok, diag::err_at_defs_cxx);
19308a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    else
19318a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor      Diag(Tok, diag::err_at_in_class);
19328a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor
19338a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    ConsumeToken();
19348a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    SkipUntil(tok::r_brace);
19358a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    return;
19368a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor  }
19378a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor
193860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  // Access declarations.
193983a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith  bool MalformedTypeSpec = false;
194060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  if (!TemplateInfo.Kind &&
194183a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith      (Tok.is(tok::identifier) || Tok.is(tok::coloncolon))) {
194283a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith    if (TryAnnotateCXXScopeToken())
194383a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith      MalformedTypeSpec = true;
194483a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith
194583a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith    bool isAccessDecl;
194683a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith    if (Tok.isNot(tok::annot_cxxscope))
194783a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith      isAccessDecl = false;
194883a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith    else if (NextToken().is(tok::identifier))
194960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      isAccessDecl = GetLookAheadToken(2).is(tok::semi);
195060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    else
195160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      isAccessDecl = NextToken().is(tok::kw_operator);
195260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
195360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    if (isAccessDecl) {
195460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // Collect the scope specifier token we annotated earlier.
195560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      CXXScopeSpec SS;
1956efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor      ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
1957efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor                                     /*EnteringContext=*/false);
195860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
195960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // Try to parse an unqualified-id.
1960e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara      SourceLocation TemplateKWLoc;
196160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      UnqualifiedId Name;
1962e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara      if (ParseUnqualifiedId(SS, false, true, true, ParsedType(),
1963e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara                             TemplateKWLoc, Name)) {
196460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        SkipUntil(tok::semi);
196560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        return;
196660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      }
196760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
196860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // TODO: recover from mistakenly-qualified operator declarations.
196960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      if (ExpectAndConsume(tok::semi,
197060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           diag::err_expected_semi_after,
197160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           "access declaration",
197260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           tok::semi))
197360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        return;
197460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
197523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.ActOnUsingDeclaration(getCurScope(), AS,
19768d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella                                    /* HasUsingKeyword */ false,
19778d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella                                    SourceLocation(),
197860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    SS, Name,
197960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    /* AttrList */ 0,
19808d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella                                    /* HasTypenameKeyword */ false,
198160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    SourceLocation());
198260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      return;
198360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    }
198460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  }
198560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
1986511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  // static_assert-declaration
1987c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne  if (Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) {
198837b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    // FIXME: Check for templates
198997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
199097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    ParseStaticAssertDeclaration(DeclEnd);
1991682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1992682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
19931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1994682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  if (Tok.is(tok::kw_template)) {
19951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(!TemplateInfo.TemplateParams &&
199637b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor           "Nested template improperly parsed?");
199797144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
19981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd,
19995f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                         AS, AccessAttrs);
2000682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
2001682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
20025aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson
2003bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  // Handle:  member-declaration ::= '__extension__' member-declaration
2004bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  if (Tok.is(tok::kw___extension__)) {
2005bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    // __extension__ silences extension warnings in the subexpression.
2006bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
2007bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ConsumeToken();
20085f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    return ParseCXXClassMemberDeclaration(AS, AccessAttrs,
20095f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                          TemplateInfo, TemplateDiags);
2010bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  }
20119cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
20124ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it
20134ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // is a bitfield.
2014a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner  ColonProtectionRAIIObject X(*this);
2015193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
20160b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributesWithRange attrs(AttrFactory);
201752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han  ParsedAttributesWithRange FnAttrs(AttrFactory);
20184e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith  // Optional C++11 attribute-specifier
20194e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith  MaybeParseCXX11Attributes(attrs);
202052b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han  // We need to keep these attributes for future diagnostic
202152b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han  // before they are taken over by declaration specifier.
202252b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han  FnAttrs.addAll(attrs.getList());
202352b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han  FnAttrs.Range = attrs.Range;
202452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han
20257f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseMicrosoftAttributes(attrs);
2026bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
20279cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_using)) {
20287f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ProhibitAttributes(attrs);
20291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20309cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    // Eat 'using'.
20319cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SourceLocation UsingLoc = ConsumeToken();
20329cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
20339cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    if (Tok.is(tok::kw_namespace)) {
20349cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      Diag(UsingLoc, diag::err_using_namespace_in_class);
20359cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SkipUntil(tok::semi, true, true);
2036ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    } else {
20379cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SourceLocation DeclEnd;
20383e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      // Otherwise, it must be a using-declaration or an alias-declaration.
203978b810559d89e996e00684335407443936ce34a1John McCall      ParseUsingDeclaration(Declarator::MemberContext, TemplateInfo,
204078b810559d89e996e00684335407443936ce34a1John McCall                            UsingLoc, DeclEnd, AS);
20419cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    }
20429cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return;
20439cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
20449cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
20452287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  // Hold late-parsed attributes so we can attach a Decl to them later.
20462287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  LateParsedAttrList CommonLateParsedAttrs;
20472287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins
20484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // decl-specifier-seq:
20494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Parse the common declaration-specifiers piece.
2050c9068d7dd94d439cec66c421115d15303e481025John McCall  ParsingDeclSpec DS(*this, TemplateDiags);
20517f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  DS.takeAttributesFrom(attrs);
205283a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith  if (MalformedTypeSpec)
205383a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith    DS.SetTypeSpecError();
20542287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins  ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class,
20552287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins                             &CommonLateParsedAttrs);
20564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
20575354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer  MultiTemplateParamsArg TemplateParams(
2058dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
2059dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
2060dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
20614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::semi)) {
20624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
206352b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han
206452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han    if (DS.isFriendSpecified())
206552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      ProhibitAttributes(FnAttrs);
206652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han
2067d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decl *TheDecl =
20680f4be74ff0273e505d383f89174ef539828424edChandler Carruth      Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS, TemplateParams);
2069c9068d7dd94d439cec66c421115d15303e481025John McCall    DS.complete(TheDecl);
207067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    return;
20714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
207207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
207354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext);
20744867347e82648d3baf09524b98b09c297a5a198fNico Weber  VirtSpecifiers VS;
20754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
2076eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  // Hold late-parsed attributes so we can attach a Decl to them later.
2077eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski  LateParsedAttrList LateParsedAttrs;
2078eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
2079a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor  SourceLocation EqualLoc;
2080a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor  bool HasInitializer = false;
2081a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor  ExprResult Init;
20823a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis  if (Tok.isNot(tok::colon)) {
2083a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner    // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
2084a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner    ColonProtectionRAIIObject X(*this);
2085a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner
20863a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Parse the first declarator.
20873a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    ParseDeclarator(DeclaratorInfo);
2088a058fd4f0a944174295f77169b438510dad389f8Richard Smith    // Error parsing the declarator?
208910bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor    if (!DeclaratorInfo.hasName()) {
20903a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      // If so, skip until the semi-colon or a }.
2091d941fa4ff0d0d64b5a541dbd4f99693bff7f6e8dSebastian Redl      SkipUntil(tok::r_brace, true, true);
20923a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (Tok.is(tok::semi))
20933a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeToken();
2094682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
20954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
20964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
20974e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith    ParseOptionalCXX11VirtSpecifierSeq(VS, getCurrentClass().IsInterface);
20984867347e82648d3baf09524b98b09c297a5a198fNico Weber
20991b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson    // If attributes exist after the declarator, but before an '{', parse them.
2100eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
21011b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson
21026a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    // MSVC permits pure specifier on inline functions declared at class scope.
21036a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    // Hence check for =0 before checking for function definition.
21044e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (getLangOpts().MicrosoftExt && Tok.is(tok::equal) &&
21056a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        DeclaratorInfo.isFunctionDeclarator() &&
21066a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        NextToken().is(tok::numeric_constant)) {
2107a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor      EqualLoc = ConsumeToken();
21086a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet      Init = ParseInitializer();
21096a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet      if (Init.isInvalid())
21106a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        SkipUntil(tok::comma, true, true);
2111a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor      else
2112a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor        HasInitializer = true;
21136a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    }
21146a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet
211545fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor    FunctionDefinitionKind DefinitionKind = FDK_Declaration;
21163a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // function-definition:
21177a614d8380297fcd2bc23986241905d97222948cRichard Smith    //
21187a614d8380297fcd2bc23986241905d97222948cRichard Smith    // In C++11, a non-function declarator followed by an open brace is a
21197a614d8380297fcd2bc23986241905d97222948cRichard Smith    // braced-init-list for an in-class member initialization, not an
21207a614d8380297fcd2bc23986241905d97222948cRichard Smith    // erroneous function definition.
212180ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith    if (Tok.is(tok::l_brace) && !getLangOpts().CPlusPlus11) {
212245fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor      DefinitionKind = FDK_Definition;
2123e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    } else if (DeclaratorInfo.isFunctionDeclarator()) {
21247a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
212545fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor        DefinitionKind = FDK_Definition;
2126e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      } else if (Tok.is(tok::equal)) {
2127e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        const Token &KW = NextToken();
212845fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor        if (KW.is(tok::kw_default))
212945fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor          DefinitionKind = FDK_Defaulted;
213045fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor        else if (KW.is(tok::kw_delete))
213145fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor          DefinitionKind = FDK_Deleted;
2132e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      }
2133e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    }
2134e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
213552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han    // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains
213652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han    // to a friend declaration, that declaration shall be a definition.
213752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han    if (DeclaratorInfo.isFunctionDeclarator() &&
213852b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han        DefinitionKind != FDK_Definition && DS.isFriendSpecified()) {
213952b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      // Diagnose attributes that appear before decl specifier:
214052b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      // [[]] friend int foo();
214152b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      ProhibitAttributes(FnAttrs);
214252b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han    }
214352b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han
214445fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor    if (DefinitionKind) {
21453a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (!DeclaratorInfo.isFunctionDeclarator()) {
214665ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu        Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params);
21473a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
214865ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu        SkipUntil(tok::r_brace, /*StopAtSemi*/false);
214952b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han
21509ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        // Consume the optional ';'
21519ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        if (Tok.is(tok::semi))
21529ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor          ConsumeToken();
2153682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
21543a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
21553a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis
21563a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
215765ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu        Diag(DeclaratorInfo.getIdentifierLoc(),
215865ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu             diag::err_function_declared_typedef);
21599ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor
21606f9a445760992a6fbff2c0b08becf35ae9eafa71Richard Smith        // Recover by treating the 'typedef' as spurious.
21616f9a445760992a6fbff2c0b08becf35ae9eafa71Richard Smith        DS.ClearStorageClassSpecs();
21623a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
21634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
2164eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      Decl *FunDecl =
21655f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen        ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo, TemplateInfo,
216645fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor                                VS, DefinitionKind, Init);
2167eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
2168fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer      if (FunDecl) {
2169fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer        for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
2170fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer          CommonLateParsedAttrs[i]->addDecl(FunDecl);
2171fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer        }
2172fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer        for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
2173fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer          LateParsedAttrs[i]->addDecl(FunDecl);
2174fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer        }
2175eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      }
2176eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski      LateParsedAttrs.clear();
2177e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
2178e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      // Consume the ';' - it's optional unless we have a delete or default
21794b0e6f1da341510c1ad83eaf4c836f3134d0156aRichard Trieu      if (Tok.is(tok::semi))
2180eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith        ConsumeExtraSemi(AfterMemberFunctionDefinition);
21819ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor
2182682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
21833a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    }
21844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
21854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
21864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // member-declarator-list:
21874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator
21884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator-list ',' member-declarator
21894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
21905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<Decl *, 8> DeclsInGroup;
219160d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult BitfieldSize;
21921c94c16317c1a35c1549e022958188eea2567089Richard Smith  bool ExpectSemi = true;
21934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
21944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  while (1) {
21954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // member-declarator:
21964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   declarator pure-specifier[opt]
21977a614d8380297fcd2bc23986241905d97222948cRichard Smith    //   declarator brace-or-equal-initializer[opt]
21984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   identifier[opt] ':' constant-expression
21994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::colon)) {
22004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
22010e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      BitfieldSize = ParseConstantExpression();
22020e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      if (BitfieldSize.isInvalid())
22034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        SkipUntil(tok::comma, true, true);
22044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
22051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2206e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    // If a simple-asm-expr is present, parse it.
2207e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    if (Tok.is(tok::kw_asm)) {
2208e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      SourceLocation Loc;
220960d7b3a319d84d688752be3870615ac0f111fb16John McCall      ExprResult AsmLabel(ParseSimpleAsm(&Loc));
2210e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      if (AsmLabel.isInvalid())
2211e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner        SkipUntil(tok::comma, true, true);
2212e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner
2213e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      DeclaratorInfo.setAsmLabel(AsmLabel.release());
2214e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      DeclaratorInfo.SetRangeEnd(Loc);
2215e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    }
2216e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner
22174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If attributes exist after the declarator, parse them.
2218eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
22194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
22207a614d8380297fcd2bc23986241905d97222948cRichard Smith    // FIXME: When g++ adds support for this, we'll need to check whether it
22217a614d8380297fcd2bc23986241905d97222948cRichard Smith    // goes before or after the GNU attributes and __asm__.
22224e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith    ParseOptionalCXX11VirtSpecifierSeq(VS, getCurrentClass().IsInterface);
22237a614d8380297fcd2bc23986241905d97222948cRichard Smith
2224ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith    InClassInitStyle HasInClassInit = ICIS_NoInit;
2225a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor    if ((Tok.is(tok::equal) || Tok.is(tok::l_brace)) && !HasInitializer) {
22267a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (BitfieldSize.get()) {
22277a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(Tok, diag::err_bitfield_member_init);
22287a614d8380297fcd2bc23986241905d97222948cRichard Smith        SkipUntil(tok::comma, true, true);
22297a614d8380297fcd2bc23986241905d97222948cRichard Smith      } else {
2230147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor        HasInitializer = true;
2231ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith        if (!DeclaratorInfo.isDeclarationOfFunction() &&
2232ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith            DeclaratorInfo.getDeclSpec().getStorageClassSpec()
2233ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith              != DeclSpec::SCS_typedef)
2234ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith          HasInClassInit = Tok.is(tok::equal) ? ICIS_CopyInit : ICIS_ListInit;
22357a614d8380297fcd2bc23986241905d97222948cRichard Smith      }
22367a614d8380297fcd2bc23986241905d97222948cRichard Smith    }
22377a614d8380297fcd2bc23986241905d97222948cRichard Smith
223807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // NOTE: If Sema is the Action module and declarator is an instance field,
2239682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    // this call will *not* return the created decl; It will return null.
224007952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // See Sema::ActOnCXXMemberDeclarator for details.
224167d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall
2242fc35cbca942ccdfe43742c1d786ed168517e0a47Rafael Espindola    NamedDecl *ThisDecl = 0;
224367d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    if (DS.isFriendSpecified()) {
224452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains
224552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      // to a friend declaration, that declaration shall be a definition.
224652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      //
224752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      // Diagnose attributes appear after friend member function declarator:
224852b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      // foo [[]] ();
224952b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      SmallVector<SourceRange, 4> Ranges;
225052b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      DeclaratorInfo.getCXX11AttributeRanges(Ranges);
225152b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      if (!Ranges.empty()) {
225209d19efaa147762f84aed55efa7930bb3616a4e5Craig Topper        for (SmallVectorImpl<SourceRange>::iterator I = Ranges.begin(),
225352b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han             E = Ranges.end(); I != E; ++I) {
225452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han          Diag((*I).getBegin(), diag::err_attributes_not_allowed)
225552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han            << *I;
225652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han        }
225752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han      }
225852b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han
2259bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall      // TODO: handle initializers, bitfields, 'delete'
226023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo,
22613fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer                                                 TemplateParams);
226237b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    } else {
226323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS,
226467d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  DeclaratorInfo,
22653fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer                                                  TemplateParams,
226667d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  BitfieldSize.release(),
2267ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith                                                  VS, HasInClassInit);
2268ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2269ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo      if (VarTemplateDecl *VT =
2270ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo              ThisDecl ? dyn_cast<VarTemplateDecl>(ThisDecl) : 0)
2271ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        // Re-direct this decl to refer to the templated decl so that we can
2272ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        // initialize it.
2273ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo        ThisDecl = VT->getTemplatedDecl();
2274ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo
2275fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer      if (ThisDecl && AccessAttrs)
22765f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen        Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs,
22775f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                         false, true);
227837b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    }
2279eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski
2280147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    // Handle the initializer.
22811d87fbaeea4a9fbbd73b3a53641f59f1673098e5David Blaikie    if (HasInClassInit != ICIS_NoInit &&
22821d87fbaeea4a9fbbd73b3a53641f59f1673098e5David Blaikie        DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
22831d87fbaeea4a9fbbd73b3a53641f59f1673098e5David Blaikie        DeclSpec::SCS_static) {
2284147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      // The initializer was deferred; parse it and cache the tokens.
2285fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer      Diag(Tok, getLangOpts().CPlusPlus11
2286fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer                    ? diag::warn_cxx98_compat_nonstatic_member_init
2287fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer                    : diag::ext_nonstatic_member_init);
22887fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith
22897a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (DeclaratorInfo.isArrayOfUnknownBound()) {
2290ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith        // C++11 [dcl.array]p3: An array bound may also be omitted when the
2291ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith        // declarator is followed by an initializer.
22927a614d8380297fcd2bc23986241905d97222948cRichard Smith        //
22937a614d8380297fcd2bc23986241905d97222948cRichard Smith        // A brace-or-equal-initializer for a member-declarator is not an
22943164c14cadbb09a05ba811602221e9156077cf44David Blaikie        // initializer in the grammar, so this is ill-formed.
22957a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(Tok, diag::err_incomplete_array_member_init);
22967a614d8380297fcd2bc23986241905d97222948cRichard Smith        SkipUntil(tok::comma, true, true);
2297fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer
2298fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer        // Avoid later warnings about a class member of incomplete type.
22993164c14cadbb09a05ba811602221e9156077cf44David Blaikie        if (ThisDecl)
23003164c14cadbb09a05ba811602221e9156077cf44David Blaikie          ThisDecl->setInvalidDecl();
23017a614d8380297fcd2bc23986241905d97222948cRichard Smith      } else
23027a614d8380297fcd2bc23986241905d97222948cRichard Smith        ParseCXXNonStaticMemberInitializer(ThisDecl);
2303147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    } else if (HasInitializer) {
2304147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      // Normal initializer.
2305a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor      if (!Init.isUsable())
2306fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer        Init = ParseCXXMemberInitializer(
2307fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer            ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
2308fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer
2309147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      if (Init.isInvalid())
2310147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor        SkipUntil(tok::comma, true, true);
2311147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      else if (ThisDecl)
231233deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl        Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid(),
2313a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith                                     DS.containsPlaceholderType());
2314fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer    } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static)
2315147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      // No initializer.
2316a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith      Actions.ActOnUninitializedDecl(ThisDecl, DS.containsPlaceholderType());
2317fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer
2318147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    if (ThisDecl) {
2319fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer      if (!ThisDecl->isInvalidDecl()) {
2320fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer        // Set the Decl for any late parsed attributes
2321fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer        for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i)
2322fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer          CommonLateParsedAttrs[i]->addDecl(ThisDecl);
2323fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer
2324fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer        for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i)
2325fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer          LateParsedAttrs[i]->addDecl(ThisDecl);
2326fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer      }
2327147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      Actions.FinalizeDeclaration(ThisDecl);
2328147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      DeclsInGroup.push_back(ThisDecl);
2329fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer
2330fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer      if (DeclaratorInfo.isFunctionDeclarator() &&
2331fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer          DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
2332fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer              DeclSpec::SCS_typedef)
2333fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer        HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
2334147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    }
2335fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer    LateParsedAttrs.clear();
2336147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor
2337147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    DeclaratorInfo.complete(ThisDecl);
23387a614d8380297fcd2bc23986241905d97222948cRichard Smith
23394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If we don't have a comma, it is either the end of the list (a ';')
23404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // or an error, bail out.
23414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.isNot(tok::comma))
23424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
23431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Consume the comma.
23451c94c16317c1a35c1549e022958188eea2567089Richard Smith    SourceLocation CommaLoc = ConsumeToken();
23461c94c16317c1a35c1549e022958188eea2567089Richard Smith
23471c94c16317c1a35c1549e022958188eea2567089Richard Smith    if (Tok.isAtStartOfLine() &&
23481c94c16317c1a35c1549e022958188eea2567089Richard Smith        !MightBeDeclarator(Declarator::MemberContext)) {
23491c94c16317c1a35c1549e022958188eea2567089Richard Smith      // This comma was followed by a line-break and something which can't be
23501c94c16317c1a35c1549e022958188eea2567089Richard Smith      // the start of a declarator. The comma was probably a typo for a
23511c94c16317c1a35c1549e022958188eea2567089Richard Smith      // semicolon.
23521c94c16317c1a35c1549e022958188eea2567089Richard Smith      Diag(CommaLoc, diag::err_expected_semi_declaration)
23531c94c16317c1a35c1549e022958188eea2567089Richard Smith        << FixItHint::CreateReplacement(CommaLoc, ";");
23541c94c16317c1a35c1549e022958188eea2567089Richard Smith      ExpectSemi = false;
23551c94c16317c1a35c1549e022958188eea2567089Richard Smith      break;
23561c94c16317c1a35c1549e022958188eea2567089Richard Smith    }
23571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Parse the next declarator.
23594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    DeclaratorInfo.clear();
23604867347e82648d3baf09524b98b09c297a5a198fNico Weber    VS.clear();
2361147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    BitfieldSize = true;
2362a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor    Init = true;
2363a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor    HasInitializer = false;
23647984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith    DeclaratorInfo.setCommaLoc(CommaLoc);
23651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2366ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling    // Attributes are only allowed on the second declarator.
23677f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseGNUAttributes(DeclaratorInfo);
23684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
23693a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    if (Tok.isNot(tok::colon))
23703a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      ParseDeclarator(DeclaratorInfo);
23714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
23724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
23731c94c16317c1a35c1549e022958188eea2567089Richard Smith  if (ExpectSemi &&
23741c94c16317c1a35c1549e022958188eea2567089Richard Smith      ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
2375ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    // Skip to end of block or statement.
2376ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    SkipUntil(tok::r_brace, true, true);
2377ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    // If we stopped at a ';', eat it.
2378ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    if (Tok.is(tok::semi)) ConsumeToken();
2379682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
23804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
23814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
23824549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola  Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);
23834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
23844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
23857a614d8380297fcd2bc23986241905d97222948cRichard Smith/// ParseCXXMemberInitializer - Parse the brace-or-equal-initializer or
23867a614d8380297fcd2bc23986241905d97222948cRichard Smith/// pure-specifier. Also detect and reject any attempted defaulted/deleted
23877a614d8380297fcd2bc23986241905d97222948cRichard Smith/// function definition. The location of the '=', if any, will be placed in
23887a614d8380297fcd2bc23986241905d97222948cRichard Smith/// EqualLoc.
23897a614d8380297fcd2bc23986241905d97222948cRichard Smith///
23907a614d8380297fcd2bc23986241905d97222948cRichard Smith///   pure-specifier:
23917a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '= 0'
239233deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///
23937a614d8380297fcd2bc23986241905d97222948cRichard Smith///   brace-or-equal-initializer:
23947a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '=' initializer-expression
239533deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///     braced-init-list
239633deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///
23977a614d8380297fcd2bc23986241905d97222948cRichard Smith///   initializer-clause:
23987a614d8380297fcd2bc23986241905d97222948cRichard Smith///     assignment-expression
239933deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///     braced-init-list
240033deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl///
24017a614d8380297fcd2bc23986241905d97222948cRichard Smith///   defaulted/deleted function-definition:
24027a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '=' 'default'
24037a614d8380297fcd2bc23986241905d97222948cRichard Smith///     '=' 'delete'
24047a614d8380297fcd2bc23986241905d97222948cRichard Smith///
24057a614d8380297fcd2bc23986241905d97222948cRichard Smith/// Prior to C++0x, the assignment-expression in an initializer-clause must
24067a614d8380297fcd2bc23986241905d97222948cRichard Smith/// be a constant-expression.
2407552e29985a710f4ced62b39d70557501bd31ca9bDouglas GregorExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,
24087a614d8380297fcd2bc23986241905d97222948cRichard Smith                                             SourceLocation &EqualLoc) {
24097a614d8380297fcd2bc23986241905d97222948cRichard Smith  assert((Tok.is(tok::equal) || Tok.is(tok::l_brace))
24107a614d8380297fcd2bc23986241905d97222948cRichard Smith         && "Data member initializer not starting with '=' or '{'");
24117a614d8380297fcd2bc23986241905d97222948cRichard Smith
2412552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor  EnterExpressionEvaluationContext Context(Actions,
2413552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor                                           Sema::PotentiallyEvaluated,
2414552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor                                           D);
24157a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (Tok.is(tok::equal)) {
24167a614d8380297fcd2bc23986241905d97222948cRichard Smith    EqualLoc = ConsumeToken();
24177a614d8380297fcd2bc23986241905d97222948cRichard Smith    if (Tok.is(tok::kw_delete)) {
24187a614d8380297fcd2bc23986241905d97222948cRichard Smith      // In principle, an initializer of '= delete p;' is legal, but it will
24197a614d8380297fcd2bc23986241905d97222948cRichard Smith      // never type-check. It's better to diagnose it as an ill-formed expression
24207a614d8380297fcd2bc23986241905d97222948cRichard Smith      // than as an ill-formed deleted non-function member.
24217a614d8380297fcd2bc23986241905d97222948cRichard Smith      // An initializer of '= delete p, foo' will never be parsed, because
24227a614d8380297fcd2bc23986241905d97222948cRichard Smith      // a top-level comma always ends the initializer expression.
24237a614d8380297fcd2bc23986241905d97222948cRichard Smith      const Token &Next = NextToken();
24247a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (IsFunction || Next.is(tok::semi) || Next.is(tok::comma) ||
24257a614d8380297fcd2bc23986241905d97222948cRichard Smith           Next.is(tok::eof)) {
24267a614d8380297fcd2bc23986241905d97222948cRichard Smith        if (IsFunction)
24277a614d8380297fcd2bc23986241905d97222948cRichard Smith          Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
24287a614d8380297fcd2bc23986241905d97222948cRichard Smith            << 1 /* delete */;
24297a614d8380297fcd2bc23986241905d97222948cRichard Smith        else
24307a614d8380297fcd2bc23986241905d97222948cRichard Smith          Diag(ConsumeToken(), diag::err_deleted_non_function);
24317a614d8380297fcd2bc23986241905d97222948cRichard Smith        return ExprResult();
24327a614d8380297fcd2bc23986241905d97222948cRichard Smith      }
24337a614d8380297fcd2bc23986241905d97222948cRichard Smith    } else if (Tok.is(tok::kw_default)) {
24347a614d8380297fcd2bc23986241905d97222948cRichard Smith      if (IsFunction)
24357a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(Tok, diag::err_default_delete_in_multiple_declaration)
24367a614d8380297fcd2bc23986241905d97222948cRichard Smith          << 0 /* default */;
24377a614d8380297fcd2bc23986241905d97222948cRichard Smith      else
24387a614d8380297fcd2bc23986241905d97222948cRichard Smith        Diag(ConsumeToken(), diag::err_default_special_members);
24397a614d8380297fcd2bc23986241905d97222948cRichard Smith      return ExprResult();
24407a614d8380297fcd2bc23986241905d97222948cRichard Smith    }
24417a614d8380297fcd2bc23986241905d97222948cRichard Smith
244233deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl  }
244333deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl  return ParseInitializer();
24447a614d8380297fcd2bc23986241905d97222948cRichard Smith}
24457a614d8380297fcd2bc23986241905d97222948cRichard Smith
24464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition.
24474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
24484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-specification:
24494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declaration member-specification[opt]
24504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         access-specifier ':' member-specification[opt]
24514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
245217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matosvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
245307fc1ba7553f2f5bf26984091197311decd9028eMichael Han                                         SourceLocation AttrFixitLoc,
2454053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith                                         ParsedAttributesWithRange &Attrs,
245517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos                                         unsigned TagType, Decl *TagDecl) {
245617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos  assert((TagType == DeclSpec::TST_struct ||
245717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos         TagType == DeclSpec::TST_interface ||
245817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos         TagType == DeclSpec::TST_union  ||
245917d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos         TagType == DeclSpec::TST_class) && "Invalid TagType!");
246017d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos
2461f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
2462f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing struct/union/class body");
24631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
246426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  // Determine whether this is a non-nested class. Note that local
246526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  // classes are *not* considered to be nested classes.
246626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  bool NonNestedClass = true;
246726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  if (!ClassStack.empty()) {
246823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    for (const Scope *S = getCurScope(); S; S = S->getParent()) {
246926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      if (S->isClassScope()) {
247026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // We're inside a class scope, so this is a nested class.
247126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        NonNestedClass = false;
2472e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall
2473e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        // The Microsoft extension __interface does not permit nested classes.
2474e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        if (getCurrentClass().IsInterface) {
2475e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall          Diag(RecordLoc, diag::err_invalid_member_in_interface)
2476e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall            << /*ErrorType=*/6
2477e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall            << (isa<NamedDecl>(TagDecl)
2478e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall                  ? cast<NamedDecl>(TagDecl)->getQualifiedNameAsString()
2479e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall                  : "<anonymous>");
2480e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        }
248126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        break;
248226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      }
248326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor
248426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      if ((S->getFlags() & Scope::FnScope)) {
248526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // If we're in a function or function template declared in the
248626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // body of a class, then this is a local class rather than a
248726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // nested class.
248826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        const Scope *Parent = S->getParent();
248926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        if (Parent->isTemplateParamScope())
249026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor          Parent = Parent->getParent();
249126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        if (Parent->isClassScope())
249226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor          break;
249326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      }
249426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor    }
249526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  }
24964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
24974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Enter a scope for the class.
24983218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
24994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
25006569d68745c8213709740337d2be52b031384f58Douglas Gregor  // Note that we are parsing a new (potentially-nested) class definition.
2501e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall  ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass,
2502e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall                                    TagType == DeclSpec::TST_interface);
25036569d68745c8213709740337d2be52b031384f58Douglas Gregor
2504ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  if (TagDecl)
250523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
2506bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
2507b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  SourceLocation FinalLoc;
2508b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson
2509b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  // Parse the optional 'final' keyword.
25104e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) {
25114e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith    assert(isCXX11FinalKeyword() && "not a class definition");
25128b11b5e6ce086fcaa7344bf84cffefcf4b53f9f6Richard Smith    FinalLoc = ConsumeToken();
2513b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson
2514e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall    if (TagType == DeclSpec::TST_interface) {
2515e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall      Diag(FinalLoc, diag::err_override_control_interface)
2516e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        << "final";
2517e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall    } else {
251880ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith      Diag(FinalLoc, getLangOpts().CPlusPlus11 ?
2519e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall           diag::warn_cxx98_compat_override_control_keyword :
2520e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall           diag::ext_override_control_keyword) << "final";
2521e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall    }
25222e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han
252307fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // Parse any C++11 attributes after 'final' keyword.
252407fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // These attributes are not allowed to appear here,
252507fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // and the only possible place for them to appertain
252607fc1ba7553f2f5bf26984091197311decd9028eMichael Han    // to the class would be between class-key and class-name.
2527053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith    CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
2528b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  }
2529cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
2530bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  if (Tok.is(tok::colon)) {
2531bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    ParseBaseClause(TagDecl);
2532bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
2533bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    if (!Tok.is(tok::l_brace)) {
2534bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall      Diag(Tok, diag::err_expected_lbrace_after_base_specifiers);
2535db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall
2536db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall      if (TagDecl)
253723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);
2538bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall      return;
2539bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    }
2540bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  }
2541bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
2542bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  assert(Tok.is(tok::l_brace));
25434a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_brace);
25444a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeOpen();
2545bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
254642a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
25472c3ee54e51d835a35bbf781c69e17f39e2ba0480Anders Carlsson    Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc,
25484a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                            T.getOpenLocation());
2549f9368159334ff86ea5fa367225c1a580977f3b03John McCall
25504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // C++ 11p3: Members of a class defined with the keyword class are private
25514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // by default. Members of a class defined with the keywords struct or union
25524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // are public by default.
25534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  AccessSpecifier CurAS;
25544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (TagType == DeclSpec::TST_class)
25554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_private;
25564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  else
25574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_public;
25585f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen  ParsedAttributes AccessAttrs(AttrFactory);
25594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
256007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  if (TagDecl) {
256107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    // While we still have something to read, read the member-declarations.
256207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
256307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Each iteration of this loop reads one member-declaration.
256407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor
25654e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
2566563a645de82231a55e221fe655b7188bf8369662Francois Pichet          Tok.is(tok::kw___if_not_exists))) {
2567563a645de82231a55e221fe655b7188bf8369662Francois Pichet        ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
2568563a645de82231a55e221fe655b7188bf8369662Francois Pichet        continue;
2569563a645de82231a55e221fe655b7188bf8369662Francois Pichet      }
2570563a645de82231a55e221fe655b7188bf8369662Francois Pichet
257107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Check for extraneous top-level semicolon.
257207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      if (Tok.is(tok::semi)) {
2573eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith        ConsumeExtraSemi(InsideStruct, TagType);
257407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        continue;
257507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      }
25761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2577aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman      if (Tok.is(tok::annot_pragma_vis)) {
2578aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman        HandlePragmaVisibility();
2579aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman        continue;
2580aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman      }
2581aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman
2582aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman      if (Tok.is(tok::annot_pragma_pack)) {
2583aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman        HandlePragmaPack();
2584aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman        continue;
2585aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman      }
2586aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman
2587f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis      if (Tok.is(tok::annot_pragma_align)) {
2588f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis        HandlePragmaAlign();
2589f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis        continue;
2590f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis      }
2591f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis
2592c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev      if (Tok.is(tok::annot_pragma_openmp)) {
2593c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev        ParseOpenMPDeclarativeDirective();
2594c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev        continue;
2595c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev      }
2596c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev
259707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      AccessSpecifier AS = getAccessSpecifierIfPresent();
259807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      if (AS != AS_none) {
259907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        // Current token is a C++ access specifier.
260007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        CurAS = AS;
260107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        SourceLocation ASLoc = Tok.getLocation();
260213f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        unsigned TokLength = Tok.getLength();
260307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        ConsumeToken();
26045f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen        AccessAttrs.clear();
26055f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen        MaybeParseGNUAttributes(AccessAttrs);
26065f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen
260713f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        SourceLocation EndLoc;
260813f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        if (Tok.is(tok::colon)) {
260913f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          EndLoc = Tok.getLocation();
261013f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          ConsumeToken();
261113f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        } else if (Tok.is(tok::semi)) {
261213f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          EndLoc = Tok.getLocation();
261313f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          ConsumeToken();
261413f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          Diag(EndLoc, diag::err_expected_colon)
261513f8daf70637f8f295134ac8e089dd7721e09085David Blaikie            << FixItHint::CreateReplacement(EndLoc, ":");
261613f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        } else {
261713f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          EndLoc = ASLoc.getLocWithOffset(TokLength);
261813f8daf70637f8f295134ac8e089dd7721e09085David Blaikie          Diag(EndLoc, diag::err_expected_colon)
261913f8daf70637f8f295134ac8e089dd7721e09085David Blaikie            << FixItHint::CreateInsertion(EndLoc, ":");
262013f8daf70637f8f295134ac8e089dd7721e09085David Blaikie        }
2621c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen
2622e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        // The Microsoft extension __interface does not permit non-public
2623e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        // access specifiers.
2624e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        if (TagType == DeclSpec::TST_interface && CurAS != AS_public) {
2625e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall          Diag(ASLoc, diag::err_access_specifier_interface)
2626e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall            << (CurAS == AS_protected);
2627e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall        }
2628e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall
2629c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen        if (Actions.ActOnAccessSpecifier(AS, ASLoc, EndLoc,
2630c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen                                         AccessAttrs.getList())) {
2631c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen          // found another attribute than only annotations
2632c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen          AccessAttrs.clear();
2633c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen        }
2634c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen
263507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        continue;
263607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      }
26374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
263807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // FIXME: Make sure we don't have a template here.
26394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
264007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Parse all the comma separated declarators.
26415f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      ParseCXXClassMemberDeclaration(CurAS, AccessAttrs.getList());
264207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    }
26431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
26444a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
264507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  } else {
264607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    SkipUntil(tok::r_brace, false, false);
26474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
26481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
26494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // If attributes exist after class contents, parse them.
26500b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
26517f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseGNUAttributes(attrs);
26524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
265342a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
265423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
26554a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                              T.getOpenLocation(),
26564a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                              T.getCloseLocation(),
26577f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                              attrs.getList());
26584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
265974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  // C++11 [class.mem]p2:
266074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  //   Within the class member-specification, the class is regarded as complete
2661a058fd4f0a944174295f77169b438510dad389f8Richard Smith  //   within function bodies, default arguments, and
266274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  //   brace-or-equal-initializers for non-static data members (including such
266374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  //   things in nested classes).
266407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  if (TagDecl && NonNestedClass) {
26654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // We are not inside a nested class. This class and its nested classes
266672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    // are complete and we can parse the delayed portions of method
2667eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    // declarations and the lexed inline method definitions, along with any
2668eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    // delayed attributes.
2669e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor    SourceLocation SavedPrevTokLocation = PrevTokLocation;
2670eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski    ParseLexedAttributes(getCurrentClass());
26716569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDeclarations(getCurrentClass());
2672a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith
2673a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith    // We've finished with all pending member declarations.
2674a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith    Actions.ActOnFinishCXXMemberDecls();
2675a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith
26767a614d8380297fcd2bc23986241905d97222948cRichard Smith    ParseLexedMemberInitializers(getCurrentClass());
26776569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDefs(getCurrentClass());
2678e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor    PrevTokLocation = SavedPrevTokLocation;
26794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
26804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
268142a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
26824a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl,
26834a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor                                     T.getCloseLocation());
2684db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall
26854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Leave the class scope.
26866569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingDef.Pop();
26878935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ClassScope.Exit();
26884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
26897ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
26907ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer,
26917ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a
26927ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers
26937ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below:
26947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
26957ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code
26967ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { };
26977ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base {
26987ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   int x;
26997ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   float f;
27007ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public:
27017ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   Derived(float f) : Base(), x(17), f(f) { }
27027ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// };
27037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode
27047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
27051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  ctor-initializer:
27061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///          ':' mem-initializer-list
27077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
27081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  mem-initializer-list:
27093fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor///          mem-initializer ...[opt]
27103fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor///          mem-initializer ...[opt] , mem-initializer-list
2711d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
27127ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
27137ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
271428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  // Poison the SEH identifiers so they are flagged as illegal in constructor initializers
271528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true);
27167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation ColonLoc = ConsumeToken();
27171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
27185f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<CXXCtorInitializer*, 4> MemInitializers;
27199db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  bool AnyErrors = false;
2720193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
27217ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  do {
27220133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    if (Tok.is(tok::code_completion)) {
2723572cf585da655522651b589101784c58902f8690Dmitri Gribenko      Actions.CodeCompleteConstructorInitializer(ConstructorDecl,
2724572cf585da655522651b589101784c58902f8690Dmitri Gribenko                                                 MemInitializers);
27257d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      return cutOffParsing();
27260133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    } else {
27270133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
27280133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      if (!MemInit.isInvalid())
27290133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor        MemInitializers.push_back(MemInit.get());
27300133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      else
27310133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor        AnyErrors = true;
27320133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    }
27330133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor
27347ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    if (Tok.is(tok::comma))
27357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      ConsumeToken();
27367ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    else if (Tok.is(tok::l_brace))
27377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
2738b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor    // If the next token looks like a base or member initializer, assume that
2739b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor    // we're just missing a comma.
2740751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor    else if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) {
2741751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor      SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
2742751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor      Diag(Loc, diag::err_ctor_init_missing_comma)
2743751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor        << FixItHint::CreateInsertion(Loc, ", ");
2744751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor    } else {
27457ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      // Skip over garbage, until we get to '{'.  Don't eat the '{'.
2746d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl      Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
27477ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      SkipUntil(tok::l_brace, true, true);
27487ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
27497ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    }
27507ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  } while (true);
27517ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
275293c8617bec98aeb769ee9f569d7ed439eec03249David Blaikie  Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, MemInitializers,
27539db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                               AnyErrors);
27547ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
27557ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
27567ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is
27577ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one
27587ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See
27597ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example.
27607ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
27617ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer:
27627ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         mem-initializer-id '(' expression-list[opt] ')'
2763dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// [C++0x] mem-initializer-id braced-init-list
27641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
27657ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id:
27667ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         '::'[opt] nested-name-specifier[opt] class-name
27677ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         identifier
2768d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
2769bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  // parse '::'[opt] nested-name-specifier[opt]
2770bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  CXXScopeSpec SS;
2771efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
2772b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TemplateTypeTy;
2773961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (Tok.is(tok::annot_template_id)) {
277425a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
2775d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor    if (TemplateId->Kind == TNK_Type_template ||
2776d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor        TemplateId->Kind == TNK_Dependent_template_name) {
2777059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
2778961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
2779b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      TemplateTypeTy = getTypeAnnotation(Tok);
2780961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    }
2781961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  }
2782f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  // Uses of decltype will already have been converted to annot_decltype by
2783f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  // ParseOptionalCXXScopeSpecifier at this point.
2784f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  if (!TemplateTypeTy && Tok.isNot(tok::identifier)
2785f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie      && Tok.isNot(tok::annot_decltype)) {
27861ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_member_or_base_name);
27877ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
27887ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
27891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2790f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  IdentifierInfo *II = 0;
2791f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  DeclSpec DS(AttrFactory);
2792f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  SourceLocation IdLoc = Tok.getLocation();
2793f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  if (Tok.is(tok::annot_decltype)) {
2794f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie    // Get the decltype expression, if there is one.
2795f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie    ParseDecltypeSpecifier(DS);
2796f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  } else {
2797f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie    if (Tok.is(tok::identifier))
2798f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie      // Get the identifier. This may be a member name or a class name,
2799f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie      // but we'll let the semantic analysis determine which it is.
2800f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie      II = Tok.getIdentifierInfo();
2801f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie    ConsumeToken();
2802f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie  }
2803f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie
28047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
28057ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Parse the '('.
280680ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith  if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
28077fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith    Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
28087fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith
28096df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    ExprResult InitList = ParseBraceInitializer();
28106df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    if (InitList.isInvalid())
28116df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      return true;
28126df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
28136df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    SourceLocation EllipsisLoc;
28146df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    if (Tok.is(tok::ellipsis))
28156df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      EllipsisLoc = ConsumeToken();
28166df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
28176df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
2818f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie                                       TemplateTypeTy, DS, IdLoc,
2819f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie                                       InitList.take(), EllipsisLoc);
2820dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl  } else if(Tok.is(tok::l_paren)) {
28214a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    BalancedDelimiterTracker T(*this, tok::l_paren);
28224a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeOpen();
2823dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl
2824dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    // Parse the optional expression-list.
28254e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer    ExprVector ArgExprs;
2826dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    CommaLocsTy CommaLocs;
2827dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
2828dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl      SkipUntil(tok::r_paren);
2829dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl      return true;
2830dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    }
28317ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
28324a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
28337ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
2834dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    SourceLocation EllipsisLoc;
2835dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    if (Tok.is(tok::ellipsis))
2836dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl      EllipsisLoc = ConsumeToken();
28377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
2838dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl    return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
2839f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie                                       TemplateTypeTy, DS, IdLoc,
2840a36bbac10f7b74ef198ec2fb0eb52dbd8a50e7f0Dmitri Gribenko                                       T.getOpenLocation(), ArgExprs,
2841a36bbac10f7b74ef198ec2fb0eb52dbd8a50e7f0Dmitri Gribenko                                       T.getCloseLocation(), EllipsisLoc);
2842dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl  }
2843dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl
284480ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith  Diag(Tok, getLangOpts().CPlusPlus11 ? diag::err_expected_lparen_or_lbrace
2845dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl                                  : diag::err_expected_lparen);
2846dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl  return true;
28477ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
28480fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
28497acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// \brief Parse a C++ exception-specification if present (C++0x [except.spec]).
28500fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
2851a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       exception-specification:
28527acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         dynamic-exception-specification
28537acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         noexcept-specification
28547acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///
28557acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///       noexcept-specification:
28567acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         'noexcept'
28577acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         'noexcept' '(' constant-expression ')'
28587acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType
2859a058fd4f0a944174295f77169b438510dad389f8Richard SmithParser::tryParseExceptionSpecification(
286074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                    SourceRange &SpecificationRange,
28615f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                    SmallVectorImpl<ParsedType> &DynamicExceptions,
28625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                    SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
2863a058fd4f0a944174295f77169b438510dad389f8Richard Smith                    ExprResult &NoexceptExpr) {
28647acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  ExceptionSpecificationType Result = EST_None;
2865a058fd4f0a944174295f77169b438510dad389f8Richard Smith
28667acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // See if there's a dynamic specification.
28677acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.is(tok::kw_throw)) {
28687acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Result = ParseDynamicExceptionSpecification(SpecificationRange,
28697acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                                DynamicExceptions,
28707acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                                DynamicExceptionRanges);
28717acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    assert(DynamicExceptions.size() == DynamicExceptionRanges.size() &&
28727acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl           "Produced different number of exception types and ranges.");
28737acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
28747acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
28757acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // If there's no noexcept specification, we're done.
28767acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.isNot(tok::kw_noexcept))
28777acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    return Result;
28787acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
2879841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith  Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
2880841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith
28817acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // If we already had a dynamic specification, parse the noexcept for,
28827acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // recovery, but emit a diagnostic and don't store the results.
28837acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SourceRange NoexceptRange;
28847acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  ExceptionSpecificationType NoexceptType = EST_None;
28857acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
28867acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SourceLocation KeywordLoc = ConsumeToken();
28877acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.is(tok::l_paren)) {
28887acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // There is an argument.
28894a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    BalancedDelimiterTracker T(*this, tok::l_paren);
28904a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeOpen();
28917acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptType = EST_ComputedNoexcept;
28927acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptExpr = ParseConstantExpression();
289360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    // The argument must be contextually convertible to bool. We use
289460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    // ActOnBooleanCondition for this purpose.
289560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    if (!NoexceptExpr.isInvalid())
289660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl      NoexceptExpr = Actions.ActOnBooleanCondition(getCurScope(), KeywordLoc,
289760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl                                                   NoexceptExpr.get());
28984a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
28994a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());
29007acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  } else {
29017acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // There is no argument.
29027acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptType = EST_BasicNoexcept;
29037acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptRange = SourceRange(KeywordLoc, KeywordLoc);
29047acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
29057acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
29067acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Result == EST_None) {
29077acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SpecificationRange = NoexceptRange;
29087acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Result = NoexceptType;
29097acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
29107acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // If there's a dynamic specification after a noexcept specification,
29117acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // parse that and ignore the results.
29127acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    if (Tok.is(tok::kw_throw)) {
29137acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
29147acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions,
29157acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                         DynamicExceptionRanges);
29167acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    }
29177acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  } else {
29187acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
29197acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
29207acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
29217acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  return Result;
29227acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl}
29237acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
292479f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smithstatic void diagnoseDynamicExceptionSpecification(
292579f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith    Parser &P, const SourceRange &Range, bool IsNoexcept) {
292679f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith  if (P.getLangOpts().CPlusPlus11) {
292779f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith    const char *Replacement = IsNoexcept ? "noexcept" : "noexcept(false)";
292879f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith    P.Diag(Range.getBegin(), diag::warn_exception_spec_deprecated) << Range;
292979f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith    P.Diag(Range.getBegin(), diag::note_exception_spec_deprecated)
293079f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith      << Replacement << FixItHint::CreateReplacement(Range, Replacement);
293179f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith  }
293279f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith}
293379f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith
29347acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// ParseDynamicExceptionSpecification - Parse a C++
29357acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification (C++ [except.spec]).
29367acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///
29377acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///       dynamic-exception-specification:
2938a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         'throw' '(' type-id-list [opt] ')'
2939a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS]    'throw' '(' '...' ')'
29401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
2941a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       type-id-list:
2942a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor///         type-id ... [opt]
2943a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor///         type-id-list ',' type-id ... [opt]
29440fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
29457acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(
29467acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                  SourceRange &SpecificationRange,
29475f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                  SmallVectorImpl<ParsedType> &Exceptions,
29485f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                  SmallVectorImpl<SourceRange> &Ranges) {
29490fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  assert(Tok.is(tok::kw_throw) && "expected throw");
29501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
29517acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SpecificationRange.setBegin(ConsumeToken());
29524a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  BalancedDelimiterTracker T(*this, tok::l_paren);
29534a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  if (T.consumeOpen()) {
29547acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Diag(Tok, diag::err_expected_lparen_after) << "throw";
29557acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SpecificationRange.setEnd(SpecificationRange.getBegin());
295660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    return EST_DynamicNone;
29570fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
29580fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
2959a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // Parse throw(...), a Microsoft extension that means "this function
2960a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // can throw anything".
2961a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  if (Tok.is(tok::ellipsis)) {
2962a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    SourceLocation EllipsisLoc = ConsumeToken();
29634e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    if (!getLangOpts().MicrosoftExt)
2964a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor      Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
29654a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    T.consumeClose();
29664a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor    SpecificationRange.setEnd(T.getCloseLocation());
296779f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith    diagnoseDynamicExceptionSpecification(*this, SpecificationRange, false);
296860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    return EST_MSAny;
2969a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  }
2970a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor
29710fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  // Parse the sequence of type-ids.
2972ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl  SourceRange Range;
29730fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  while (Tok.isNot(tok::r_paren)) {
2974ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    TypeResult Res(ParseTypeName(&Range));
29757acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
2976a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor    if (Tok.is(tok::ellipsis)) {
2977a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      // C++0x [temp.variadic]p5:
2978a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      //   - In a dynamic-exception-specification (15.4); the pattern is a
2979a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      //     type-id.
2980a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      SourceLocation Ellipsis = ConsumeToken();
29817acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      Range.setEnd(Ellipsis);
2982a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      if (!Res.isInvalid())
2983a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor        Res = Actions.ActOnPackExpansion(Res.get(), Ellipsis);
2984a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor    }
29857acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
2986ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    if (!Res.isInvalid()) {
29877dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl      Exceptions.push_back(Res.get());
2988ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl      Ranges.push_back(Range);
2989ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    }
2990a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor
29910fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor    if (Tok.is(tok::comma))
29920fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      ConsumeToken();
29937dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl    else
29940fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      break;
29950fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
29960fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
29974a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  T.consumeClose();
29984a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor  SpecificationRange.setEnd(T.getCloseLocation());
299979f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith  diagnoseDynamicExceptionSpecification(*this, SpecificationRange,
300079f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith                                        Exceptions.empty());
300160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl  return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic;
30020fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor}
30036569d68745c8213709740337d2be52b031384f58Douglas Gregor
3004dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// ParseTrailingReturnType - Parse a trailing return type on a new-style
3005dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// function declaration.
3006ae7902c4293d9de8b9591759513f0d075f45022aDouglas GregorTypeResult Parser::ParseTrailingReturnType(SourceRange &Range) {
3007dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  assert(Tok.is(tok::arrow) && "expected arrow");
3008dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
3009dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  ConsumeToken();
3010dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
30117796eb5643244f3134834253ce5ea89107ac21c1Richard Smith  return ParseTypeName(&Range, Declarator::TrailingReturnContext);
3012dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor}
3013dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
30146569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief We have just started parsing the definition of a new class,
30156569d68745c8213709740337d2be52b031384f58Douglas Gregor/// so push that class onto our stack of classes that is currently
30166569d68745c8213709740337d2be52b031384f58Douglas Gregor/// being parsed.
3017eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallSema::ParsingClassState
3018e402e72273cde2a64fa6097c1fe93f500038675dJohn McCallParser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass,
3019e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall                         bool IsInterface) {
302026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  assert((NonNestedClass || !ClassStack.empty()) &&
30216569d68745c8213709740337d2be52b031384f58Douglas Gregor         "Nested class without outer class");
3022e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall  ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass, IsInterface));
3023eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  return Actions.PushParsingClass();
30246569d68745c8213709740337d2be52b031384f58Douglas Gregor}
30256569d68745c8213709740337d2be52b031384f58Douglas Gregor
30266569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Deallocate the given parsed class and all of its nested
30276569d68745c8213709740337d2be52b031384f58Douglas Gregor/// classes.
30286569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
3029d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I)
3030d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    delete Class->LateParsedDeclarations[I];
30316569d68745c8213709740337d2be52b031384f58Douglas Gregor  delete Class;
30326569d68745c8213709740337d2be52b031384f58Douglas Gregor}
30336569d68745c8213709740337d2be52b031384f58Douglas Gregor
30346569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Pop the top class of the stack of classes that are
30356569d68745c8213709740337d2be52b031384f58Douglas Gregor/// currently being parsed.
30366569d68745c8213709740337d2be52b031384f58Douglas Gregor///
30376569d68745c8213709740337d2be52b031384f58Douglas Gregor/// This routine should be called when we have finished parsing the
30386569d68745c8213709740337d2be52b031384f58Douglas Gregor/// definition of a class, but have not yet popped the Scope
30396569d68745c8213709740337d2be52b031384f58Douglas Gregor/// associated with the class's definition.
3040eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Parser::PopParsingClass(Sema::ParsingClassState state) {
30416569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");
30421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3043eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  Actions.PopParsingClass(state);
3044eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
30456569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingClass *Victim = ClassStack.top();
30466569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.pop();
30476569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (Victim->TopLevelClass) {
30486569d68745c8213709740337d2be52b031384f58Douglas Gregor    // Deallocate all of the nested classes of this class,
30496569d68745c8213709740337d2be52b031384f58Douglas Gregor    // recursively: we don't need to keep any of this information.
30506569d68745c8213709740337d2be52b031384f58Douglas Gregor    DeallocateParsedClasses(Victim);
30516569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
30521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
30536569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Missing top-level class?");
30546569d68745c8213709740337d2be52b031384f58Douglas Gregor
3055d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (Victim->LateParsedDeclarations.empty()) {
30566569d68745c8213709740337d2be52b031384f58Douglas Gregor    // The victim is a nested class, but we will not need to perform
30576569d68745c8213709740337d2be52b031384f58Douglas Gregor    // any processing after the definition of this class since it has
30586569d68745c8213709740337d2be52b031384f58Douglas Gregor    // no members whose handling was delayed. Therefore, we can just
30596569d68745c8213709740337d2be52b031384f58Douglas Gregor    // remove this nested class.
3060d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    DeallocateParsedClasses(Victim);
30616569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
30626569d68745c8213709740337d2be52b031384f58Douglas Gregor  }
30636569d68745c8213709740337d2be52b031384f58Douglas Gregor
30646569d68745c8213709740337d2be52b031384f58Douglas Gregor  // This nested class has some members that will need to be processed
30656569d68745c8213709740337d2be52b031384f58Douglas Gregor  // after the top-level class is completely defined. Therefore, add
30666569d68745c8213709740337d2be52b031384f58Douglas Gregor  // it to the list of nested classes within its parent.
306723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  assert(getCurScope()->isClassScope() && "Nested class outside of class scope?");
3068d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ClassStack.top()->LateParsedDeclarations.push_back(new LateParsedClass(this, Victim));
306923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope();
30706569d68745c8213709740337d2be52b031384f58Douglas Gregor}
3071bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
3072c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// \brief Try to parse an 'identifier' which appears within an attribute-token.
3073c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///
3074c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// \return the parsed identifier on success, and 0 if the next token is not an
3075c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute-token.
3076c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///
3077c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// C++11 [dcl.attr.grammar]p3:
3078c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///   If a keyword or an alternative token that satisfies the syntactic
3079c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///   requirements of an identifier is contained in an attribute-token,
3080c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///   it is considered an identifier.
3081c56298d87a9df507805a548d7d515e8b511df2c0Richard SmithIdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(SourceLocation &Loc) {
3082c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  switch (Tok.getKind()) {
3083c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  default:
3084c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    // Identifiers and keywords have identifier info attached.
3085c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
3086c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      Loc = ConsumeToken();
3087c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      return II;
3088c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    }
3089c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    return 0;
3090c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith
3091c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::ampamp:       // 'and'
3092c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::pipe:         // 'bitor'
3093c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::pipepipe:     // 'or'
3094c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::caret:        // 'xor'
3095c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::tilde:        // 'compl'
3096c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::amp:          // 'bitand'
3097c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::ampequal:     // 'and_eq'
3098c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::pipeequal:    // 'or_eq'
3099c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::caretequal:   // 'xor_eq'
3100c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::exclaim:      // 'not'
3101c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  case tok::exclaimequal: // 'not_eq'
3102c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    // Alternative tokens do not have identifier info, but their spelling
3103c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    // starts with an alphabetical character.
3104cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    SmallString<8> SpellingBuf;
3105c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    StringRef Spelling = PP.getSpelling(Tok.getLocation(), SpellingBuf);
31063f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose    if (isLetter(Spelling[0])) {
3107c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      Loc = ConsumeToken();
31080eb7526cd2524af78fb9a2a2522045fb25fc3d27Benjamin Kramer      return &PP.getIdentifierTable().get(Spelling);
3109c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    }
3110c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    return 0;
3111c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  }
3112c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith}
3113c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith
31146880f492365cc4fa4c941aa83688635003ee7498Michael Hanstatic bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,
31156880f492365cc4fa4c941aa83688635003ee7498Michael Han                                               IdentifierInfo *ScopeName) {
31166880f492365cc4fa4c941aa83688635003ee7498Michael Han  switch (AttributeList::getKind(AttrName, ScopeName,
31176880f492365cc4fa4c941aa83688635003ee7498Michael Han                                 AttributeList::AS_CXX11)) {
31186880f492365cc4fa4c941aa83688635003ee7498Michael Han  case AttributeList::AT_CarriesDependency:
31196880f492365cc4fa4c941aa83688635003ee7498Michael Han  case AttributeList::AT_FallThrough:
3120cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith  case AttributeList::AT_CXX11NoReturn: {
31216880f492365cc4fa4c941aa83688635003ee7498Michael Han    return true;
31226880f492365cc4fa4c941aa83688635003ee7498Michael Han  }
31236880f492365cc4fa4c941aa83688635003ee7498Michael Han
31246880f492365cc4fa4c941aa83688635003ee7498Michael Han  default:
31256880f492365cc4fa4c941aa83688635003ee7498Michael Han    return false;
31266880f492365cc4fa4c941aa83688635003ee7498Michael Han  }
31276880f492365cc4fa4c941aa83688635003ee7498Michael Han}
31286880f492365cc4fa4c941aa83688635003ee7498Michael Han
3129c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier. Currently
31303497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// only parses standard attributes.
3131bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
31326ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-specifier:
3133bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' '[' attribute-list ']' ']'
313482d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne///         alignment-specifier
3135bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
31366ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-list:
3137bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute[opt]
3138bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-list ',' attribute[opt]
3139c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///         attribute '...'
3140c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith///         attribute-list ',' attribute '...'
3141bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
31426ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute:
3143bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-token attribute-argument-clause[opt]
3144bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
31456ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-token:
3146bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
3147bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-scoped-token
3148bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
31496ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-scoped-token:
3150bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-namespace '::' identifier
3151bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
31526ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-namespace:
3153bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
3154bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
31556ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-argument-clause:
3156bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
3157bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
31586ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] balanced-token-seq:
3159bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token
3160bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token-seq balanced-token
3161bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
31626ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] balanced-token:
3163bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
3164bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' balanced-token-seq ']'
3165bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '{' balanced-token-seq '}'
3166bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         any token but '(', ')', '[', ']', '{', or '}'
3167c56298d87a9df507805a548d7d515e8b511df2c0Richard Smithvoid Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
31683497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne                                          SourceLocation *endLoc) {
316982d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne  if (Tok.is(tok::kw_alignas)) {
317041be673e93ed225b45479557b20ff19b3082bae8Richard Smith    Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas);
317182d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne    ParseAlignmentSpecifier(attrs, endLoc);
317282d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne    return;
317382d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne  }
317482d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne
3175bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
31766ee326af4e77e6f05973486097884d7431f2108dRichard Smith      && "Not a C++11 attribute list");
3177bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
317841be673e93ed225b45479557b20ff19b3082bae8Richard Smith  Diag(Tok.getLocation(), diag::warn_cxx98_compat_attribute);
317941be673e93ed225b45479557b20ff19b3082bae8Richard Smith
3180bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
3181bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
3182193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
3183cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith  llvm::SmallDenseMap<IdentifierInfo*, SourceLocation, 4> SeenAttrs;
3184cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith
3185c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith  while (Tok.isNot(tok::r_square)) {
3186bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // attribute not present
3187bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::comma)) {
3188bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
3189bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      continue;
3190bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
3191bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
3192c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    SourceLocation ScopeLoc, AttrLoc;
3193c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    IdentifierInfo *ScopeName = 0, *AttrName = 0;
3194c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith
3195c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    AttrName = TryParseCXX11AttributeIdentifier(AttrLoc);
3196c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    if (!AttrName)
3197c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      // Break out to the "expected ']'" diagnostic.
3198c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      break;
3199193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
3200bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // scoped attribute
3201bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::coloncolon)) {
3202bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
3203bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
3204c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      ScopeName = AttrName;
3205c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      ScopeLoc = AttrLoc;
3206c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith
3207c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      AttrName = TryParseCXX11AttributeIdentifier(AttrLoc);
3208c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith      if (!AttrName) {
3209bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        Diag(Tok.getLocation(), diag::err_expected_ident);
3210bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        SkipUntil(tok::r_square, tok::comma, true, true);
3211bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        continue;
3212bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
3213bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
3214bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
32156880f492365cc4fa4c941aa83688635003ee7498Michael Han    bool StandardAttr = IsBuiltInOrStandardCXX11Attribute(AttrName,ScopeName);
3216bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    bool AttrParsed = false;
32176880f492365cc4fa4c941aa83688635003ee7498Michael Han
3218cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith    if (StandardAttr &&
3219cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith        !SeenAttrs.insert(std::make_pair(AttrName, AttrLoc)).second)
3220cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith      Diag(AttrLoc, diag::err_cxx11_attribute_repeated)
3221cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith        << AttrName << SourceRange(SeenAttrs[AttrName]);
3222cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith
32236880f492365cc4fa4c941aa83688635003ee7498Michael Han    // Parse attribute arguments
32246880f492365cc4fa4c941aa83688635003ee7498Michael Han    if (Tok.is(tok::l_paren)) {
32256880f492365cc4fa4c941aa83688635003ee7498Michael Han      if (ScopeName && ScopeName->getName() == "gnu") {
32266880f492365cc4fa4c941aa83688635003ee7498Michael Han        ParseGNUAttributeArgs(AttrName, AttrLoc, attrs, endLoc,
32276880f492365cc4fa4c941aa83688635003ee7498Michael Han                              ScopeName, ScopeLoc, AttributeList::AS_CXX11);
32286880f492365cc4fa4c941aa83688635003ee7498Michael Han        AttrParsed = true;
32296880f492365cc4fa4c941aa83688635003ee7498Michael Han      } else {
32306880f492365cc4fa4c941aa83688635003ee7498Michael Han        if (StandardAttr)
32316880f492365cc4fa4c941aa83688635003ee7498Michael Han          Diag(Tok.getLocation(), diag::err_cxx11_attribute_forbids_arguments)
32326880f492365cc4fa4c941aa83688635003ee7498Michael Han            << AttrName->getName();
32336880f492365cc4fa4c941aa83688635003ee7498Michael Han
32346880f492365cc4fa4c941aa83688635003ee7498Michael Han        // FIXME: handle other formats of c++11 attribute arguments
32356880f492365cc4fa4c941aa83688635003ee7498Michael Han        ConsumeParen();
32366880f492365cc4fa4c941aa83688635003ee7498Michael Han        SkipUntil(tok::r_paren, false);
3237bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
32386880f492365cc4fa4c941aa83688635003ee7498Michael Han    }
3239bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
32406880f492365cc4fa4c941aa83688635003ee7498Michael Han    if (!AttrParsed)
3241e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith      attrs.addNew(AttrName,
3242e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                   SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc,
3243e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                               AttrLoc),
3244e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith                   ScopeName, ScopeLoc, 0,
324593f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt                   SourceLocation(), 0, 0, AttributeList::AS_CXX11);
32466ee326af4e77e6f05973486097884d7431f2108dRichard Smith
3247c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    if (Tok.is(tok::ellipsis)) {
32486ee326af4e77e6f05973486097884d7431f2108dRichard Smith      ConsumeToken();
32496880f492365cc4fa4c941aa83688635003ee7498Michael Han
32506880f492365cc4fa4c941aa83688635003ee7498Michael Han      Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis)
32516880f492365cc4fa4c941aa83688635003ee7498Michael Han        << AttrName->getName();
3252c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    }
3253bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
3254bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
3255bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
3256bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
32573497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne  if (endLoc)
32583497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne    *endLoc = Tok.getLocation();
3259bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
3260bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
32613497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne}
32623497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne
32632edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt/// ParseCXX11Attributes - Parse a C++11 attribute-specifier-seq.
32643497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne///
32653497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// attribute-specifier-seq:
32663497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne///       attribute-specifier-seq[opt] attribute-specifier
3267c56298d87a9df507805a548d7d515e8b511df2c0Richard Smithvoid Parser::ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
32683497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne                                  SourceLocation *endLoc) {
3269672edb0a04a5273e3a501f3b196844c125290780Richard Smith  assert(getLangOpts().CPlusPlus11);
3270672edb0a04a5273e3a501f3b196844c125290780Richard Smith
32713497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne  SourceLocation StartLoc = Tok.getLocation(), Loc;
32723497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne  if (!endLoc)
32733497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne    endLoc = &Loc;
32743497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne
32758828ee7faa42f889ade3bb635dc5f1338be671b1Douglas Gregor  do {
3276c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith    ParseCXX11AttributeSpecifier(attrs, endLoc);
32776ee326af4e77e6f05973486097884d7431f2108dRichard Smith  } while (isCXX11AttributeSpecifier());
3278bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
32793497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne  attrs.Range = SourceRange(StartLoc, *endLoc);
3280bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
3281bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
3282334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ParseMicrosoftAttributes - Parse a Microsoft attribute [Attr]
3283334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///
3284334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute:
3285334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             '[' token-seq ']'
3286334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///
3287334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute-seq:
3288334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             ms-attribute[opt]
3289334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             ms-attribute ms-attribute-seq
32907f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCallvoid Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs,
32917f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                      SourceLocation *endLoc) {
3292334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
3293334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet
3294334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  while (Tok.is(tok::l_square)) {
32956ee326af4e77e6f05973486097884d7431f2108dRichard Smith    // FIXME: If this is actually a C++11 attribute, parse it as one.
3296334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    ConsumeBracket();
3297334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    SkipUntil(tok::r_square, true, true);
32987f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    if (endLoc) *endLoc = Tok.getLocation();
3299334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
3300334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  }
3301334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet}
3302563a645de82231a55e221fe655b7188bf8369662Francois Pichet
3303563a645de82231a55e221fe655b7188bf8369662Francois Pichetvoid Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType,
3304563a645de82231a55e221fe655b7188bf8369662Francois Pichet                                                    AccessSpecifier& CurAS) {
33053896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  IfExistsCondition Result;
3306563a645de82231a55e221fe655b7188bf8369662Francois Pichet  if (ParseMicrosoftIfExistsCondition(Result))
3307563a645de82231a55e221fe655b7188bf8369662Francois Pichet    return;
3308563a645de82231a55e221fe655b7188bf8369662Francois Pichet
33093896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  BalancedDelimiterTracker Braces(*this, tok::l_brace);
33103896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  if (Braces.consumeOpen()) {
3311563a645de82231a55e221fe655b7188bf8369662Francois Pichet    Diag(Tok, diag::err_expected_lbrace);
3312563a645de82231a55e221fe655b7188bf8369662Francois Pichet    return;
3313563a645de82231a55e221fe655b7188bf8369662Francois Pichet  }
3314563a645de82231a55e221fe655b7188bf8369662Francois Pichet
33153896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  switch (Result.Behavior) {
33163896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Parse:
33173896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    // Parse the declarations below.
33183896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    break;
33193896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
33203896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Dependent:
33213896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
33223896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor      << Result.IsIfExists;
33233896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    // Fall through to skip.
33243896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
33253896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  case IEB_Skip:
33263896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor    Braces.skipToEnd();
3327563a645de82231a55e221fe655b7188bf8369662Francois Pichet    return;
3328563a645de82231a55e221fe655b7188bf8369662Francois Pichet  }
3329563a645de82231a55e221fe655b7188bf8369662Francois Pichet
33303896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
3331563a645de82231a55e221fe655b7188bf8369662Francois Pichet    // __if_exists, __if_not_exists can nest.
3332563a645de82231a55e221fe655b7188bf8369662Francois Pichet    if ((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists))) {
3333563a645de82231a55e221fe655b7188bf8369662Francois Pichet      ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
3334563a645de82231a55e221fe655b7188bf8369662Francois Pichet      continue;
3335563a645de82231a55e221fe655b7188bf8369662Francois Pichet    }
3336563a645de82231a55e221fe655b7188bf8369662Francois Pichet
3337563a645de82231a55e221fe655b7188bf8369662Francois Pichet    // Check for extraneous top-level semicolon.
3338563a645de82231a55e221fe655b7188bf8369662Francois Pichet    if (Tok.is(tok::semi)) {
3339eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith      ConsumeExtraSemi(InsideStruct, TagType);
3340563a645de82231a55e221fe655b7188bf8369662Francois Pichet      continue;
3341563a645de82231a55e221fe655b7188bf8369662Francois Pichet    }
3342563a645de82231a55e221fe655b7188bf8369662Francois Pichet
3343563a645de82231a55e221fe655b7188bf8369662Francois Pichet    AccessSpecifier AS = getAccessSpecifierIfPresent();
3344563a645de82231a55e221fe655b7188bf8369662Francois Pichet    if (AS != AS_none) {
3345563a645de82231a55e221fe655b7188bf8369662Francois Pichet      // Current token is a C++ access specifier.
3346563a645de82231a55e221fe655b7188bf8369662Francois Pichet      CurAS = AS;
3347563a645de82231a55e221fe655b7188bf8369662Francois Pichet      SourceLocation ASLoc = Tok.getLocation();
3348563a645de82231a55e221fe655b7188bf8369662Francois Pichet      ConsumeToken();
3349563a645de82231a55e221fe655b7188bf8369662Francois Pichet      if (Tok.is(tok::colon))
3350563a645de82231a55e221fe655b7188bf8369662Francois Pichet        Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
3351563a645de82231a55e221fe655b7188bf8369662Francois Pichet      else
3352563a645de82231a55e221fe655b7188bf8369662Francois Pichet        Diag(Tok, diag::err_expected_colon);
3353563a645de82231a55e221fe655b7188bf8369662Francois Pichet      ConsumeToken();
3354563a645de82231a55e221fe655b7188bf8369662Francois Pichet      continue;
3355563a645de82231a55e221fe655b7188bf8369662Francois Pichet    }
3356563a645de82231a55e221fe655b7188bf8369662Francois Pichet
3357563a645de82231a55e221fe655b7188bf8369662Francois Pichet    // Parse all the comma separated declarators.
33585f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen    ParseCXXClassMemberDeclaration(CurAS, 0);
3359563a645de82231a55e221fe655b7188bf8369662Francois Pichet  }
33603896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor
33613896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor  Braces.consumeClose();
3362563a645de82231a55e221fe655b7188bf8369662Francois Pichet}
3363