ParseDeclCXX.cpp revision db5d44b775c60166074acd184ca9f1981c10c2a7
18f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -----------------------===//
28f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//
38f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//                     The LLVM Compiler Infrastructure
48f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
78f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//
88f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===----------------------------------------------------------------------===//
98f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//
108f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//  This file implements the C++ Declaration portions of the Parser interfaces.
118f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//
128f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===----------------------------------------------------------------------===//
138f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner
140c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson#include "clang/Basic/OperatorKinds.h"
151b7f89846f10681ce3cbe89ef5d60691d55bd918Douglas Gregor#include "clang/Parse/Parser.h"
16500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h"
1719510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
1819510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/Scope.h"
1919510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/ParsedTemplate.h"
20f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall#include "clang/Sema/PrettyDeclStackTrace.h"
21d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner#include "RAIIObjectsForParser.h"
228f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattnerusing namespace clang;
238f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner
248f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// ParseNamespace - We know that the current token is a namespace keyword. This
25d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// may either be a top level namespace or a block-level namespace alias. If
26d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// there was an inline keyword, it has already been parsed.
278f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
288f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       namespace-definition: [C++ 7.3: basic.namespace]
298f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         named-namespace-definition
308f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         unnamed-namespace-definition
318f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
328f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       unnamed-namespace-definition:
33d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' attributes[opt] '{' namespace-body '}'
348f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
358f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       named-namespace-definition:
368f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         original-namespace-definition
378f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         extension-namespace-definition
388f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
398f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       original-namespace-definition:
40d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' identifier attributes[opt]
41d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///             '{' namespace-body '}'
428f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
438f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       extension-namespace-definition:
44d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///         'inline'[opt] 'namespace' original-namespace-name
45d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl///             '{' namespace-body '}'
461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
478f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       namespace-alias-definition:  [C++ 7.3.2: namespace.alias]
488f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         'namespace' identifier '=' qualified-namespace-specifier ';'
498f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
50d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespace(unsigned Context,
51d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl                             SourceLocation &DeclEnd,
52d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl                             SourceLocation InlineLoc) {
5304d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
548f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation NamespaceLoc = ConsumeToken();  // eat the 'namespace'.
551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5649f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
5723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteNamespaceDecl(getCurScope());
58dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
5949f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
60193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
618f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation IdentLoc;
628f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  IdentifierInfo *Ident = 0;
636a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
646a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  Token attrTok;
651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6604d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  if (Tok.is(tok::identifier)) {
678f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    Ident = Tok.getIdentifierInfo();
688f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    IdentLoc = ConsumeToken();  // eat the identifier.
698f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  }
701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
718f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  // Read label attributes, if present.
720b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
736a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::kw___attribute)) {
746a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor    attrTok = Tok;
757f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
766a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
786a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::equal)) {
797f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    if (!attrs.empty())
806a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor      Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
81d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl    if (InlineLoc.isValid())
82d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl      Diag(InlineLoc, diag::err_inline_namespace_alias)
83d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl          << FixItHint::CreateRemoval(InlineLoc);
846a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
8597144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
866a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
885144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  if (Tok.isNot(tok::l_brace)) {
891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Diag(Tok, Ident ? diag::err_expected_lbrace :
905144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner         diag::err_expected_ident_lbrace);
91d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
925144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  }
931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
945144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  SourceLocation LBrace = ConsumeBrace();
952d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
9623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() ||
9723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      getCurScope()->isInObjcMethodScope() || getCurScope()->getBlockParent() ||
9823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      getCurScope()->getFnParent()) {
9995f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor    Diag(LBrace, diag::err_namespace_nonnamespace_scope);
10095f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor    SkipUntil(tok::r_brace, false);
101d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
10295f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor  }
10395f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor
10488e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl  // If we're still good, complain about inline namespaces in non-C++0x now.
10588e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl  if (!getLang().CPlusPlus0x && InlineLoc.isValid())
10688e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl    Diag(InlineLoc, diag::ext_inline_namespace);
10788e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl
1085144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Enter a scope for the namespace.
1095144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  ParseScope NamespaceScope(this, Scope::DeclScope);
1102d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
111d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *NamespcDecl =
112acba90f30876b4140b738f0d3dd0e50724053a96Abramo Bagnara    Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, NamespaceLoc,
113acba90f30876b4140b738f0d3dd0e50724053a96Abramo Bagnara                                   IdentLoc, Ident, LBrace, attrs.getList());
1142d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
115f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc,
116f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing namespace");
1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
118bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
1190b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    ParsedAttributesWithRange attrs(AttrFactory);
1207f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseCXX0XAttributes(attrs);
1217f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseMicrosoftAttributes(attrs);
1227f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseExternalDeclaration(attrs);
123bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1255144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Leave the namespace scope.
1265144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  NamespaceScope.Exit();
1278ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis
12897144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBrace);
12997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  Actions.ActOnFinishNamespaceDef(NamespcDecl, RBraceLoc);
1302d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
13197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = RBraceLoc;
1325144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  return NamespcDecl;
1338f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner}
134c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
135f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
136f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// alias definition.
137f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson///
138d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
1390b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  SourceLocation AliasLoc,
1400b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  IdentifierInfo *Alias,
1410b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                                  SourceLocation &DeclEnd) {
142f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  assert(Tok.is(tok::equal) && "Not equal token");
1431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
144f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  ConsumeToken(); // eat the '='.
1451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14649f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
14723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteNamespaceAliasDecl(getCurScope());
148dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
14949f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
150193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
151f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  CXXScopeSpec SS;
152f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse (optional) nested-name-specifier.
153b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
154f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
155f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
156f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    Diag(Tok, diag::err_expected_namespace_name);
157f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    // Skip to end of the definition and eat the ';'.
158f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    SkipUntil(tok::semi);
159d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
160f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  }
161f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
162f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse identifier.
16303bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  IdentifierInfo *Ident = Tok.getIdentifierInfo();
16403bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  SourceLocation IdentLoc = ConsumeToken();
1651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
166f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Eat the ';'.
16797144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
1686869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name,
1696869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner                   "", tok::semi);
1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc, Alias,
17203bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson                                        SS, IdentLoc, Ident);
173f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson}
174f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
175c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal
176c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen.
177c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
178c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///       linkage-specification: [C++ 7.5p2: dcl.link]
179c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal '{' declaration-seq[opt] '}'
180c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal declaration
181c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
1827d64271b162eaf5cae264ff64465b28af623dc17Chris LattnerDecl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
183c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor  assert(Tok.is(tok::string_literal) && "Not a string literal!");
184193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  llvm::SmallString<8> LangBuffer;
185453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  bool Invalid = false;
186453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  llvm::StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid);
187453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  if (Invalid)
188d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
189c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
190c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  SourceLocation Loc = ConsumeStringToken();
191c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
192074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  ParseScope LinkageScope(this, Scope::DeclScope);
193d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *LinkageSpec
19423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    = Actions.ActOnStartLinkageSpecification(getCurScope(),
195a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                             DS.getSourceRange().getBegin(),
196d56638180014e60538cd666cd11fde6d4698e051Benjamin Kramer                                             Loc, Lang,
197a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                      Tok.is(tok::l_brace) ? Tok.getLocation()
198074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                           : SourceLocation());
199074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
2000b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributesWithRange attrs(AttrFactory);
2017f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseCXX0XAttributes(attrs);
2027f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseMicrosoftAttributes(attrs);
203193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
204074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (Tok.isNot(tok::l_brace)) {
205f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // Reset the source range in DS, as the leading "extern"
206f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // does not really belong to the inner declaration ...
207f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    DS.SetRangeStart(SourceLocation());
208f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    DS.SetRangeEnd(SourceLocation());
209f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara    // ... but anyway remember that such an "extern" was seen.
21035f9a196ef897b9559de25aaecd957208f0b4f59Abramo Bagnara    DS.setExternInLinkageSpec(true);
2117f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseExternalDeclaration(attrs, &DS);
21223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
213074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                   SourceLocation());
2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
215f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor
21663a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor  DS.abort();
21763a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor
2187f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  ProhibitAttributes(attrs);
219bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
220f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  SourceLocation LBrace = ConsumeBrace();
221f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
2220b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall    ParsedAttributesWithRange attrs(AttrFactory);
2237f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseCXX0XAttributes(attrs);
2247f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseMicrosoftAttributes(attrs);
2257f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseExternalDeclaration(attrs);
226f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  }
227c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
228f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
2297d64271b162eaf5cae264ff64465b28af623dc17Chris Lattner  return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
2307d64271b162eaf5cae264ff64465b28af623dc17Chris Lattner                                                 RBrace);
231c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner}
232e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
233f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
234f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'.
235d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
23678b810559d89e996e00684335407443936ce34a1John McCall                                         const ParsedTemplateInfo &TemplateInfo,
23778b810559d89e996e00684335407443936ce34a1John McCall                                               SourceLocation &DeclEnd,
2387f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                             ParsedAttributesWithRange &attrs) {
239f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_using) && "Not using token");
240f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
241f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'using'.
242f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation UsingLoc = ConsumeToken();
243f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
24449f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
24523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteUsing(getCurScope());
246dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
24749f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
248193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
24978b810559d89e996e00684335407443936ce34a1John McCall  // 'using namespace' means this is a using-directive.
25078b810559d89e996e00684335407443936ce34a1John McCall  if (Tok.is(tok::kw_namespace)) {
25178b810559d89e996e00684335407443936ce34a1John McCall    // Template parameters are always an error here.
25278b810559d89e996e00684335407443936ce34a1John McCall    if (TemplateInfo.Kind) {
25378b810559d89e996e00684335407443936ce34a1John McCall      SourceRange R = TemplateInfo.getSourceRange();
25478b810559d89e996e00684335407443936ce34a1John McCall      Diag(UsingLoc, diag::err_templated_using_directive)
25578b810559d89e996e00684335407443936ce34a1John McCall        << R << FixItHint::CreateRemoval(R);
25678b810559d89e996e00684335407443936ce34a1John McCall    }
25778b810559d89e996e00684335407443936ce34a1John McCall
2587f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
25978b810559d89e996e00684335407443936ce34a1John McCall  }
260bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
261162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  // Otherwise, it must be a using-declaration or an alias-declaration.
26278b810559d89e996e00684335407443936ce34a1John McCall
26378b810559d89e996e00684335407443936ce34a1John McCall  // Using declarations can't have attributes.
2647f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  ProhibitAttributes(attrs);
2652f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner
26678b810559d89e996e00684335407443936ce34a1John McCall  return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd);
267f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
268f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
269f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes
270f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed.
271f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
272f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       using-directive: [C++ 7.3.p4: namespace.udir]
273f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
274f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name ;
275f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive:
276f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
277f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name attributes[opt] ;
278f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
279d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirective(unsigned Context,
28078b810559d89e996e00684335407443936ce34a1John McCall                                  SourceLocation UsingLoc,
28178b810559d89e996e00684335407443936ce34a1John McCall                                  SourceLocation &DeclEnd,
2827f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                  ParsedAttributes &attrs) {
283f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
284f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
285f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'namespace'.
286f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation NamespcLoc = ConsumeToken();
287f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
28849f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
28923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteUsingDirective(getCurScope());
290dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
29149f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
292193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
293f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  CXXScopeSpec SS;
294f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse (optional) nested-name-specifier.
295b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
296f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
297f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  IdentifierInfo *NamespcName = 0;
298f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation IdentLoc = SourceLocation();
299f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
300f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse namespace-name.
301823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
302f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    Diag(Tok, diag::err_expected_namespace_name);
303f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // If there was invalid namespace name, skip to end of decl, and eat ';'.
304f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    SkipUntil(tok::semi);
305f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
306d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
307f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  }
3081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
309823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse identifier.
310823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  NamespcName = Tok.getIdentifierInfo();
311823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  IdentLoc = ConsumeToken();
3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
313823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse (optional) attributes (most likely GNU strong-using extension).
314bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  bool GNUAttr = false;
315bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Tok.is(tok::kw___attribute)) {
316bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    GNUAttr = true;
3177f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
318bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
3191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
320823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Eat ';'.
32197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
3226869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi,
3239ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                   GNUAttr ? diag::err_expected_semi_after_attribute_list
3249ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                           : diag::err_expected_semi_after_namespace_name,
3259ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor                   "", tok::semi);
326f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
32723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
3287f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                     IdentLoc, NamespcName, attrs.getList());
329f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
330f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
331162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration.
332162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// Assumes that 'using' was already seen.
333f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
334f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///     using-declaration: [C++ 7.3.p3: namespace.udecl]
335f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       'using' 'typename'[opt] ::[opt] nested-name-specifier
3369cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///               unqualified-id
3379cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///       'using' :: unqualified-id
338f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
339162e1c1b487352434552147967c3dd296ebee2f7Richard Smith///     alias-declaration: C++0x [decl.typedef]p2
340162e1c1b487352434552147967c3dd296ebee2f7Richard Smith///       'using' identifier = type-id ;
341162e1c1b487352434552147967c3dd296ebee2f7Richard Smith///
342d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDeclaration(unsigned Context,
34378b810559d89e996e00684335407443936ce34a1John McCall                                    const ParsedTemplateInfo &TemplateInfo,
34478b810559d89e996e00684335407443936ce34a1John McCall                                    SourceLocation UsingLoc,
34578b810559d89e996e00684335407443936ce34a1John McCall                                    SourceLocation &DeclEnd,
34678b810559d89e996e00684335407443936ce34a1John McCall                                    AccessSpecifier AS) {
3479cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  CXXScopeSpec SS;
3487ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall  SourceLocation TypenameLoc;
3499cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  bool IsTypeName;
3509cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3519cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Ignore optional 'typename'.
35212c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // FIXME: This is wrong; we should parse this as a typename-specifier.
3539cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_typename)) {
3547ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall    TypenameLoc = Tok.getLocation();
3559cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    ConsumeToken();
3569cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = true;
3579cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
3589cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  else
3599cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = false;
3609cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3619cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Parse nested-name-specifier.
362b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
3639cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3649cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Check nested-name specifier.
3659cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (SS.isInvalid()) {
3669cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
367d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
3689cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
3691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
370193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  // Parse the unqualified-id. We allow parsing of both constructor and
37112c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // destructor names and allow the action module to diagnose any semantic
37212c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // errors.
37312c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  UnqualifiedId Name;
374193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  if (ParseUnqualifiedId(SS,
37512c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*EnteringContext=*/false,
37612c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*AllowDestructorName=*/true,
377193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                         /*AllowConstructorName=*/true,
378b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                         ParsedType(),
37912c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         Name)) {
3809cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
381d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
3829cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
383193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
3840b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
385162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
386162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  // Maybe this is an alias-declaration.
387162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  bool IsAliasDecl = Tok.is(tok::equal);
388162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  TypeResult TypeAlias;
389162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (IsAliasDecl) {
3903e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    // TODO: Attribute support. C++0x attributes may appear before the equals.
3913e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    // Where can GNU attributes appear?
392162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    ConsumeToken();
393162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
394162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    if (!getLang().CPlusPlus0x)
395162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(Tok.getLocation(), diag::ext_alias_declaration);
396162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
3973e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    // Type alias templates cannot be specialized.
3983e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    int SpecKind = -1;
399536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&
400536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith        Name.getKind() == UnqualifiedId::IK_TemplateId)
4013e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 0;
4023e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)
4033e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 1;
4043e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
4053e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SpecKind = 2;
4063e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    if (SpecKind != -1) {
4073e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SourceRange Range;
4083e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      if (SpecKind == 0)
4093e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        Range = SourceRange(Name.TemplateId->LAngleLoc,
4103e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                            Name.TemplateId->RAngleLoc);
4113e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      else
4123e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        Range = TemplateInfo.getSourceRange();
4133e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      Diag(Range.getBegin(), diag::err_alias_declaration_specialization)
4143e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith        << SpecKind << Range;
4153e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      SkipUntil(tok::semi);
4163e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      return 0;
4173e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    }
4183e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith
419162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    // Name must be an identifier.
420162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    if (Name.getKind() != UnqualifiedId::IK_Identifier) {
421162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(Name.StartLocation, diag::err_alias_declaration_not_identifier);
422162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      // No removal fixit: can't recover from this.
423162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      SkipUntil(tok::semi);
424162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      return 0;
425162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    } else if (IsTypeName)
426162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(TypenameLoc, diag::err_alias_declaration_not_identifier)
427162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        << FixItHint::CreateRemoval(SourceRange(TypenameLoc,
428162e1c1b487352434552147967c3dd296ebee2f7Richard Smith                             SS.isNotEmpty() ? SS.getEndLoc() : TypenameLoc));
429162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    else if (SS.isNotEmpty())
430162e1c1b487352434552147967c3dd296ebee2f7Richard Smith      Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
431162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        << FixItHint::CreateRemoval(SS.getRange());
432162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
4333e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    TypeAlias = ParseTypeName(0, TemplateInfo.Kind ?
4343e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                              Declarator::AliasTemplateContext :
4353e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                              Declarator::AliasDeclContext);
436162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  } else
437162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    // Parse (optional) attributes (most likely GNU strong-using extension).
438162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    MaybeParseGNUAttributes(attrs);
4391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4409cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Eat ';'.
4419cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  DeclEnd = Tok.getLocation();
4429cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
443162e1c1b487352434552147967c3dd296ebee2f7Richard Smith                   !attrs.empty() ? "attributes list" :
444162e1c1b487352434552147967c3dd296ebee2f7Richard Smith                   IsAliasDecl ? "alias declaration" : "using declaration",
44512c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                   tok::semi);
4469cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
44778b810559d89e996e00684335407443936ce34a1John McCall  // Diagnose an attempt to declare a templated using-declaration.
4483e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  // In C++0x, alias-declarations can be templates:
449162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  //   template <...> using id = type;
4503e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  if (TemplateInfo.Kind && !IsAliasDecl) {
45178b810559d89e996e00684335407443936ce34a1John McCall    SourceRange R = TemplateInfo.getSourceRange();
45278b810559d89e996e00684335407443936ce34a1John McCall    Diag(UsingLoc, diag::err_templated_using_declaration)
45378b810559d89e996e00684335407443936ce34a1John McCall      << R << FixItHint::CreateRemoval(R);
45478b810559d89e996e00684335407443936ce34a1John McCall
45578b810559d89e996e00684335407443936ce34a1John McCall    // Unfortunately, we have to bail out instead of recovering by
45678b810559d89e996e00684335407443936ce34a1John McCall    // ignoring the parameters, just in case the nested name specifier
45778b810559d89e996e00684335407443936ce34a1John McCall    // depends on the parameters.
45878b810559d89e996e00684335407443936ce34a1John McCall    return 0;
45978b810559d89e996e00684335407443936ce34a1John McCall  }
46078b810559d89e996e00684335407443936ce34a1John McCall
4613e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  if (IsAliasDecl) {
4623e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
4633e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    MultiTemplateParamsArg TemplateParamsArg(Actions,
4643e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      TemplateParams ? TemplateParams->data() : 0,
4653e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      TemplateParams ? TemplateParams->size() : 0);
4663e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith    return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,
4673e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith                                         UsingLoc, Name, TypeAlias);
4683e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith  }
469162e1c1b487352434552147967c3dd296ebee2f7Richard Smith
4708113ecfa4e41e2c888b1794389dfe3bce6386493Ted Kremenek  return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS,
4717f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                       Name, attrs.getList(),
4727f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                       IsTypeName, TypenameLoc);
473f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
474f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
475c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// ParseStaticAssertDeclaration - Parse C++0x or C1X static_assert-declaration.
476511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
477c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// [C++0x] static_assert-declaration:
478c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///           static_assert ( constant-expression  ,  string-literal  ) ;
479c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///
480c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// [C1X]   static_assert-declaration:
481c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne///           _Static_assert ( constant-expression  ,  string-literal  ) ;
482511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
483d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
484c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne  assert((Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) &&
485c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne         "Not a static_assert declaration");
486c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne
487c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne  if (Tok.is(tok::kw__Static_assert) && !getLang().C1X)
488c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne    Diag(Tok, diag::ext_c1x_static_assert);
489c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne
490511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation StaticAssertLoc = ConsumeToken();
4911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
492511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (Tok.isNot(tok::l_paren)) {
493511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_lparen);
494d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
495511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
4961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
497511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation LParenLoc = ConsumeParen();
498e0762c92110dfdcdd207db461a4ea17afd168f1eDouglas Gregor
49960d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult AssertExpr(ParseConstantExpression());
500511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (AssertExpr.isInvalid()) {
501511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    SkipUntil(tok::semi);
502d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
503511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
5041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
505ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
506d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
507ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson
508511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (Tok.isNot(tok::string_literal)) {
509511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_string_literal);
510511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    SkipUntil(tok::semi);
511d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
512511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
5131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
51460d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult AssertMessage(ParseStringLiteralExpression());
5151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (AssertMessage.isInvalid())
516d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    return 0;
517511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
518a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
5191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
52097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
5219ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor  ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert);
522511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
5239ae2f076ca5ab1feb3ba95629099ec2319833701John McCall  return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc,
5249ae2f076ca5ab1feb3ba95629099ec2319833701John McCall                                              AssertExpr.take(),
525a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                              AssertMessage.take(),
526a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara                                              RParenLoc);
527511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson}
528511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
5296fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// ParseDecltypeSpecifier - Parse a C++0x decltype specifier.
5306fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
5316fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 'decltype' ( expression )
5326fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
5336fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlssonvoid Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
5346fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  assert(Tok.is(tok::kw_decltype) && "Not a decltype specifier");
5356fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
5366fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation StartLoc = ConsumeToken();
5376fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation LParenLoc = Tok.getLocation();
5381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
5406fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson                       "decltype")) {
5416fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    SkipUntil(tok::r_paren);
5426fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
5436fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  }
5441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5456fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Parse the expression
5461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5476fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // C++0x [dcl.type.simple]p4:
5486fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  //   The operand of the decltype specifier is an unevaluated operand.
5496fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  EnterExpressionEvaluationContext Unevaluated(Actions,
550f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                               Sema::Unevaluated);
55160d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult Result = ParseExpression();
5526fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (Result.isInvalid()) {
5536fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    SkipUntil(tok::r_paren);
5546fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
5556fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  }
5561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5576fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Match the ')'
5586fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation RParenLoc;
5596fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (Tok.is(tok::r_paren))
5606fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    RParenLoc = ConsumeParen();
5616fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  else
5626fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    MatchRHSPunctuation(tok::r_paren, LParenLoc);
5631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5646fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (RParenLoc.isInvalid())
5656fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
5666fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
5676fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  const char *PrevSpec = 0;
568fec54013fcd0eb72642741584ca04c1bc292bef8John McCall  unsigned DiagID;
5696fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Check for duplicate type specifiers (e.g. "int decltype(a)").
5701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec,
571fec54013fcd0eb72642741584ca04c1bc292bef8John McCall                         DiagID, Result.release()))
572fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
5736fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson}
5746fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
575db5d44b775c60166074acd184ca9f1981c10c2a7Sean Huntvoid Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) {
576db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  assert(Tok.is(tok::kw___underlying_type) &&
577db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt         "Not an underlying type specifier");
578db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
579db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  SourceLocation StartLoc = ConsumeToken();
580db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  SourceLocation LParenLoc = Tok.getLocation();
581db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
582db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
583db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt                       "__underlying_type")) {
584db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    SkipUntil(tok::r_paren);
585db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
586db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  }
587db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
588db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  TypeResult Result = ParseTypeName();
589db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  if (Result.isInvalid()) {
590db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    SkipUntil(tok::r_paren);
591db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
592db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  }
593db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
594db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  // Match the ')'
595db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  SourceLocation RParenLoc;
596db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  if (Tok.is(tok::r_paren))
597db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    RParenLoc = ConsumeParen();
598db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  else
599db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    MatchRHSPunctuation(tok::r_paren, LParenLoc);
600db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
601db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  if (RParenLoc.isInvalid())
602db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    return;
603db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
604db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  const char *PrevSpec = 0;
605db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  unsigned DiagID;
606db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt  if (DS.SetTypeSpecType(DeclSpec::TST_underlying_type, StartLoc, PrevSpec,
607db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt                         DiagID, Result.release()))
608db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt    Diag(StartLoc, DiagID) << PrevSpec;
609db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt}
610db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt
61142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// ParseClassName - Parse a C++ class-name, which names a class. Note
61242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// that we only check that the result names a type; semantic analysis
61342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// will need to verify that the type names a class. The result is
6147f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor/// either a type or NULL, depending on whether a type name was
61542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// found.
61642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///
61742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///       class-name: [C++ 9.1]
61842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///         identifier
6197f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor///         simple-template-id
6201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
62131a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas GregorParser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
622059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                          CXXScopeSpec &SS) {
6237f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  // Check whether we have a template-id that names a type.
6247f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  if (Tok.is(tok::annot_template_id)) {
6251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    TemplateIdAnnotation *TemplateId
6267f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
627d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor    if (TemplateId->Kind == TNK_Type_template ||
628d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor        TemplateId->Kind == TNK_Dependent_template_name) {
629059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
6307f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
6317f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
632b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      ParsedType Type = getTypeAnnotation(Tok);
6337f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      EndLocation = Tok.getAnnotationEndLoc();
6347f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      ConsumeToken();
63531a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor
63631a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      if (Type)
63731a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor        return Type;
63831a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      return true;
6397f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    }
6407f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
6417f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    // Fall through to produce an error below.
6427f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  }
6437f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
64442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  if (Tok.isNot(tok::identifier)) {
6451ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_class_name);
64631a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
64742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
64842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
64984d0a19828599e8623223632d59447fd498999cfDouglas Gregor  IdentifierInfo *Id = Tok.getIdentifierInfo();
65084d0a19828599e8623223632d59447fd498999cfDouglas Gregor  SourceLocation IdLoc = ConsumeToken();
65184d0a19828599e8623223632d59447fd498999cfDouglas Gregor
65284d0a19828599e8623223632d59447fd498999cfDouglas Gregor  if (Tok.is(tok::less)) {
65384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // It looks the user intended to write a template-id here, but the
65484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // template-name was wrong. Try to fix that.
65584d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateNameKind TNK = TNK_Type_template;
65684d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateTy Template;
65723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(),
658059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                             &SS, Template, TNK)) {
65984d0a19828599e8623223632d59447fd498999cfDouglas Gregor      Diag(IdLoc, diag::err_unknown_template_name)
66084d0a19828599e8623223632d59447fd498999cfDouglas Gregor        << Id;
66184d0a19828599e8623223632d59447fd498999cfDouglas Gregor    }
662193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
66384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (!Template)
66484d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
66584d0a19828599e8623223632d59447fd498999cfDouglas Gregor
666193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam    // Form the template name
66784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    UnqualifiedId TemplateName;
66884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateName.setIdentifier(Id, IdLoc);
669193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
67084d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // Parse the full template-id, then turn it into a type.
67184d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName,
67284d0a19828599e8623223632d59447fd498999cfDouglas Gregor                                SourceLocation(), true))
67384d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
67484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (TNK == TNK_Dependent_template_name)
675059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
676193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
67784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // If we didn't end up with a typename token, there's nothing more we
67884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // can do.
67984d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (Tok.isNot(tok::annot_typename))
68084d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
681193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
68284d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // Retrieve the type from the annotation token, consume that token, and
68384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // return.
68484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    EndLocation = Tok.getAnnotationEndLoc();
685b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    ParsedType Type = getTypeAnnotation(Tok);
68684d0a19828599e8623223632d59447fd498999cfDouglas Gregor    ConsumeToken();
68784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    return Type;
68884d0a19828599e8623223632d59447fd498999cfDouglas Gregor  }
68984d0a19828599e8623223632d59447fd498999cfDouglas Gregor
69042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // We have an identifier; check whether it is actually a type.
691059101f922de6eb765601459925f4c8914420b23Douglas Gregor  ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true,
6929e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor                                        false, ParsedType(),
6939e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor                                        /*NonTrivialTypeSourceInfo=*/true);
694193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  if (!Type) {
695124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor    Diag(IdLoc, diag::err_expected_class_name);
69631a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
69742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
69842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
69942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Consume the identifier.
70084d0a19828599e8623223632d59447fd498999cfDouglas Gregor  EndLocation = IdLoc;
7015606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
7025606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  // Fake up a Declarator to use with ActOnTypeName.
7030b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  DeclSpec DS(AttrFactory);
7045606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetRangeStart(IdLoc);
7055606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetRangeEnd(EndLocation);
706059101f922de6eb765601459925f4c8914420b23Douglas Gregor  DS.getTypeSpecScope() = SS;
7075606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
7085606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  const char *PrevSpec = 0;
7095606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  unsigned DiagID;
7105606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type);
7115606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky
7125606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
7135606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky  return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
71442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor}
71542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
716e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
717e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
718e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that
719d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl/// cannot start a definition. If SuppressDeclarations is true, we do know.
720e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
721e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-specifier: [C++ class]
722e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}'
723e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}' attributes[opt]
724e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-head:
725e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key identifier[opt] base-clause[opt]
726e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier identifier base-clause[opt]
727e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier[opt] simple-template-id
728e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          base-clause[opt]
729e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   class-key attributes[opt] identifier[opt] base-clause[opt]
7301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier
731e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          identifier base-clause[opt]
7321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier[opt]
733e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          simple-template-id base-clause[opt]
734e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-key:
735e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'class'
736e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
737e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
738e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
739e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       elaborated-type-specifier: [C++ dcl.type.elab]
7401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] identifier
7411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
7421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///                          simple-template-id
743e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
744e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  Note that the C++ class-specifier and elaborated-type-specifier,
745e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  together, subsume the C99 struct-or-union-specifier:
746e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
747e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union-specifier: [C99 6.7.2.1]
748e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier[opt] '{' struct-contents '}'
749e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier
750e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier[opt] '{' struct-contents
751e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                                                         '}' attributes[opt]
752e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier
753e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union:
754e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
755e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
7564c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattnervoid Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
7574c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner                                 SourceLocation StartLoc, DeclSpec &DS,
7584d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                 const ParsedTemplateInfo &TemplateInfo,
759d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl                                 AccessSpecifier AS, bool SuppressDeclarations){
7604c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  DeclSpec::TST TagType;
7614c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  if (TagTokKind == tok::kw_struct)
7624c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_struct;
7634c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  else if (TagTokKind == tok::kw_class)
7644c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_class;
7654c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  else {
7664c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    assert(TagTokKind == tok::kw_union && "Not a class specifier");
7674c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_union;
7684c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  }
769e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
770374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  if (Tok.is(tok::code_completion)) {
771374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor    // Code completion for a struct, class, or union name.
77223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.CodeCompleteTag(getCurScope(), TagType);
773dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
774374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  }
775193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
776926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // C++03 [temp.explicit] 14.7.2/8:
777926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //   The usual access checking rules do not apply to names used to specify
778926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //   explicit instantiations.
779926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  //
780926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // As an extension we do not perform access checking on the names used to
781926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // specify explicit specializations either. This is important to allow
782926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // specializing traits classes for private types.
783926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  bool SuppressingAccessChecks = false;
784926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
785926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth      TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization) {
786926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth    Actions.ActOnStartSuppressingAccessChecks();
787926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth    SuppressingAccessChecks = true;
788926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  }
789926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
7900b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
791e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If attributes exist after tag, parse them.
792e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw___attribute))
7937f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseGNUAttributes(attrs);
794e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
795f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff  // If declspecs exist after tag, parse them.
796b1d397c23e1f8fd8b404d5731d531e7500f7140dJohn McCall  while (Tok.is(tok::kw___declspec))
7977f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ParseMicrosoftDeclSpec(attrs);
798193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
799bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // If C++0x attributes exist here, parse them.
800bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Are we consistent with the ordering of parsing of different
801bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // styles of attributes?
8027f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseCXX0XAttributes(attrs);
8031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
80420c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley  if (TagType == DeclSpec::TST_struct &&
805b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      !Tok.is(tok::identifier) &&
806b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      Tok.getIdentifierInfo() &&
807b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor      (Tok.is(tok::kw___is_arithmetic) ||
808b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_convertible) ||
80920c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley       Tok.is(tok::kw___is_empty) ||
810b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_floating_point) ||
811b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_function) ||
81220c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley       Tok.is(tok::kw___is_fundamental) ||
813b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_integral) ||
814b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_member_function_pointer) ||
815b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_member_pointer) ||
816b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_pod) ||
817b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_pointer) ||
818b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_same) ||
819877222e2491bbc40a5c74cc100c540983f306b70Douglas Gregor       Tok.is(tok::kw___is_scalar) ||
820b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_signed) ||
821b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_unsigned) ||
822b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor       Tok.is(tok::kw___is_void))) {
823b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // GNU libstdc++ 4.2 and libc++ uaw certain intrinsic names as the
824b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // name of struct templates, but some are keywords in GCC >= 4.3
825b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // and Clang. Therefore, when we see the token sequence "struct
826b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // X", make X into a normal identifier rather than a keyword, to
827b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor    // allow libstdc++ 4.2 and libc++ to work properly.
828646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis    Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
829b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.setKind(tok::identifier);
830b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  }
8311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
832eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse the (optional) nested-name-specifier.
833aa87d33309f505b68c3bfc17486c93e4d224b24fJohn McCall  CXXScopeSpec &SS = DS.getTypeSpecScope();
83408d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  if (getLang().CPlusPlus) {
83508d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    // "FOO : BAR" is not a potential typo for "FOO::BAR".
83608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    ColonProtectionRAIIObject X(*this);
837193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
838b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), true))
839207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      DS.SetTypeSpecError();
8409ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall    if (SS.isSet())
84108d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner      if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
84208d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner        Diag(Tok, diag::err_expected_ident);
84308d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  }
844cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
8452cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor  TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
8462cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor
847cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  // Parse the (optional) class name or simple-template-id.
848e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  IdentifierInfo *Name = 0;
849e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation NameLoc;
85039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  TemplateIdAnnotation *TemplateId = 0;
851e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::identifier)) {
852e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    Name = Tok.getIdentifierInfo();
853e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    NameLoc = ConsumeToken();
854193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
8555ee3734c0b5222a7c445591a1f14102c1b3a289bDouglas Gregor    if (Tok.is(tok::less) && getLang().CPlusPlus) {
856193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      // The name was supposed to refer to a template, but didn't.
8572cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // Eat the template argument list and try to continue parsing this as
8582cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // a class (or template thereof).
8592cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      TemplateArgList TemplateArgs;
8602cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      SourceLocation LAngleLoc, RAngleLoc;
861059101f922de6eb765601459925f4c8914420b23Douglas Gregor      if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, SS,
8622cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor                                           true, LAngleLoc,
863314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor                                           TemplateArgs, RAngleLoc)) {
8642cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // We couldn't parse the template argument list at all, so don't
8652cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // try to give any location information for the list.
8662cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        LAngleLoc = RAngleLoc = SourceLocation();
8672cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
868193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
8692cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      Diag(NameLoc, diag::err_explicit_spec_non_template)
870c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
8712cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << (TagType == DeclSpec::TST_class? 0
8722cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor            : TagType == DeclSpec::TST_struct? 1
8732cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor            : 2)
8742cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << Name
8752cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << SourceRange(LAngleLoc, RAngleLoc);
876193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
877193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      // Strip off the last template parameter list if it was empty, since
878c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      // we've removed its template argument list.
879c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
880c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        if (TemplateParams && TemplateParams->size() > 1) {
881c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams->pop_back();
882c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        } else {
883c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams = 0;
884193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam          const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
885c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor            = ParsedTemplateInfo::NonTemplate;
886c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        }
887c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      } else if (TemplateInfo.Kind
888c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor                                == ParsedTemplateInfo::ExplicitInstantiation) {
889c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        // Pretend this is just a forward declaration.
8902cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        TemplateParams = 0;
891193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam        const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
8922cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor          = ParsedTemplateInfo::NonTemplate;
893193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam        const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc
894c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
895c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc
896c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
8972cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
8982cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor    }
89939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  } else if (Tok.is(tok::annot_template_id)) {
90039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
90139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    NameLoc = ConsumeToken();
902cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
903059101f922de6eb765601459925f4c8914420b23Douglas Gregor    if (TemplateId->Kind != TNK_Type_template &&
904059101f922de6eb765601459925f4c8914420b23Douglas Gregor        TemplateId->Kind != TNK_Dependent_template_name) {
90539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // The template-name in the simple-template-id refers to
90639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // something other than a class template. Give an appropriate
90739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // error message and skip to the ';'.
90839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SourceRange Range(NameLoc);
90939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      if (SS.isNotEmpty())
91039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        Range.setBegin(SS.getBeginLoc());
91139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
91239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
91339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        << Name << static_cast<int>(TemplateId->Kind) << Range;
9141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
91539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      DS.SetTypeSpecError();
91639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SkipUntil(tok::semi, false, true);
91739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      TemplateId->Destroy();
918926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth      if (SuppressingAccessChecks)
919926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth        Actions.ActOnStopSuppressingAccessChecks();
920926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
92139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      return;
922cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    }
923e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
924e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
925926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // As soon as we're finished parsing the class's template-id, turn access
926926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  // checking back on.
927926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth  if (SuppressingAccessChecks)
928926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth    Actions.ActOnStopSuppressingAccessChecks();
929926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth
93067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  // There are four options here.  If we have 'struct foo;', then this
93167d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  // is either a forward declaration or a friend declaration, which
932cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson  // have to be treated differently.  If we have 'struct foo {...',
9331d20927fd0a08c26ef0e86e26f42073fd582ff77Anders Carlsson  // 'struct foo :...' or 'struct foo final[opt]' then this is a
934cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson  // definition. Otherwise we have something like 'struct foo xyz', a reference.
935d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // However, in some contexts, things look like declarations but are just
936d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // references, e.g.
937d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // new struct s;
938d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // or
939d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // &T::operator struct s;
940d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // For these, SuppressDeclarations is true.
941f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  Sema::TagUseKind TUK;
942d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  if (SuppressDeclarations)
943f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = Sema::TUK_Reference;
944cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson  else if (Tok.is(tok::l_brace) ||
945cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson           (getLang().CPlusPlus && Tok.is(tok::colon)) ||
9468a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson           isCXX0XFinalKeyword()) {
947d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    if (DS.isFriendSpecified()) {
948d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // C++ [class.friend]p2:
949d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      //   A class shall not be defined in a friend declaration.
950d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      Diag(Tok.getLocation(), diag::err_friend_decl_defines_class)
951d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor        << SourceRange(DS.getFriendSpecLoc());
952d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor
953d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Skip everything up to the semicolon, so that this looks like a proper
954d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // friend class (or template thereof) declaration.
955d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      SkipUntil(tok::semi, true, true);
956f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall      TUK = Sema::TUK_Friend;
957d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    } else {
958d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Okay, this is a class definition.
959f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall      TUK = Sema::TUK_Definition;
960d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    }
961d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor  } else if (Tok.is(tok::semi))
962f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
963e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  else
964f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    TUK = Sema::TUK_Reference;
965e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
966207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall  if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error ||
967f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                               TUK != Sema::TUK_Definition)) {
968207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall    if (DS.getTypeSpecType() != DeclSpec::TST_error) {
969207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      // We have a declaration or reference to an anonymous class.
970207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall      Diag(StartLoc, diag::err_anon_type_definition)
971207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall        << DeclSpec::getSpecifierName(TagType);
972207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall    }
973e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
974e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SkipUntil(tok::comma, true);
97539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
97639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    if (TemplateId)
97739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      TemplateId->Destroy();
978e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    return;
979e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
980e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
981ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  // Create the tag portion of the class or class template.
982d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  DeclResult TagOrTempResult = true; // invalid
983d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  TypeResult TypeResult = true; // invalid
9844d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
985402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor  bool Owned = false;
986f1bbbb49f06a7462476cd88166fccda5feb15cabJohn McCall  if (TemplateId) {
9874d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // Explicit specialization, class template partial specialization,
9884d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // or explicit instantiation.
9891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ASTTemplateArgsPtr TemplateArgsPtr(Actions,
99039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->getTemplateArgs(),
99139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->NumArgs);
9924d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
993f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        TUK == Sema::TUK_Declaration) {
9944d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit instantiation of a class template.
9954d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
99623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        = Actions.ActOnExplicitInstantiation(getCurScope(),
99745f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                             TemplateInfo.ExternLoc,
9981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateInfo.TemplateLoc,
9994d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TagType,
10001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             StartLoc,
10014d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             SS,
10022b5289b6fd7e3d9899868410a498c081c9595662John McCall                                             TemplateId->Template,
10031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->TemplateNameLoc,
10041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->LAngleLoc,
10054d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateArgsPtr,
10061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->RAngleLoc,
10077f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                             attrs.getList());
100874256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall
100974256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // Friend template-ids are treated as references unless
101074256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // they have template headers, in which case they're ill-formed
101174256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // (FIXME: "template <class T> friend class A<T>::B<int>;").
101274256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // We diagnose this error in ActOnClassTemplateSpecialization.
1013f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    } else if (TUK == Sema::TUK_Reference ||
1014f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall               (TUK == Sema::TUK_Friend &&
101574256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall                TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
1016059101f922de6eb765601459925f4c8914420b23Douglas Gregor      TypeResult = Actions.ActOnTagTemplateIdType(TUK, TagType,
1017059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  StartLoc,
1018059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->SS,
1019059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->Template,
1020059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->TemplateNameLoc,
1021059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->LAngleLoc,
1022059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateArgsPtr,
1023059101f922de6eb765601459925f4c8914420b23Douglas Gregor                                                  TemplateId->RAngleLoc);
10244d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    } else {
10254d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit specialization or a class template
10264d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // partial specialization.
10274d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TemplateParameterLists FakedParamLists;
10284d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
10294d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
10304d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // This looks like an explicit instantiation, because we have
10314d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // something like
10324d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
10334d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //   template class Foo<X>
10344d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
10353f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor        // but it actually has a definition. Most likely, this was
10364d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // meant to be an explicit specialization, but the user forgot
10374d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // the '<>' after 'template'.
1038f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        assert(TUK == Sema::TUK_Definition && "Expected a definition here");
10394d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
10401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        SourceLocation LAngleLoc
10414d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
10421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        Diag(TemplateId->TemplateNameLoc,
10434d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor             diag::err_explicit_instantiation_with_definition)
10444d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          << SourceRange(TemplateInfo.TemplateLoc)
1045849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor          << FixItHint::CreateInsertion(LAngleLoc, "<>");
10464d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
10474d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // Create a fake template parameter list that contains only
10484d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // "template<>", so that we treat this construct as a class
10494d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // template specialization.
10504d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        FakedParamLists.push_back(
10511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          Actions.ActOnTemplateParameterList(0, SourceLocation(),
10524d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateInfo.TemplateLoc,
10531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             LAngleLoc,
10541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             0, 0,
10554d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             LAngleLoc));
10564d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        TemplateParams = &FakedParamLists;
10574d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      }
10584d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
10594d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // Build the class template specialization.
10604d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
106123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK,
106239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       StartLoc, SS,
10632b5289b6fd7e3d9899868410a498c081c9595662John McCall                       TemplateId->Template,
10641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->TemplateNameLoc,
10651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->LAngleLoc,
106639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       TemplateArgsPtr,
10671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->RAngleLoc,
10687f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                       attrs.getList(),
1069f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                       MultiTemplateParamsArg(Actions,
1070cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                    TemplateParams? &(*TemplateParams)[0] : 0,
1071cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                 TemplateParams? TemplateParams->size() : 0));
10724d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    }
107339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    TemplateId->Destroy();
10743f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1075f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall             TUK == Sema::TUK_Declaration) {
10763f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Explicit instantiation of a member of a class template
10773f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // specialization, e.g.,
10783f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
10793f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //   template struct Outer<int>::Inner;
10803f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
10813f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    TagOrTempResult
108223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      = Actions.ActOnExplicitInstantiation(getCurScope(),
108345f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                           TemplateInfo.ExternLoc,
10841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TemplateInfo.TemplateLoc,
10851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TagType, StartLoc, SS, Name,
10867f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                           NameLoc, attrs.getList());
10879a34edb710917798aa30263374f624f13b594605John McCall  } else if (TUK == Sema::TUK_Friend &&
10889a34edb710917798aa30263374f624f13b594605John McCall             TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
10899a34edb710917798aa30263374f624f13b594605John McCall    TagOrTempResult =
10909a34edb710917798aa30263374f624f13b594605John McCall      Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(),
10919a34edb710917798aa30263374f624f13b594605John McCall                                      TagType, StartLoc, SS,
10927f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                      Name, NameLoc, attrs.getList(),
10939a34edb710917798aa30263374f624f13b594605John McCall                                      MultiTemplateParamsArg(Actions,
10949a34edb710917798aa30263374f624f13b594605John McCall                                    TemplateParams? &(*TemplateParams)[0] : 0,
10959a34edb710917798aa30263374f624f13b594605John McCall                                 TemplateParams? TemplateParams->size() : 0));
10963f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else {
10973f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1098f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall        TUK == Sema::TUK_Definition) {
10993f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor      // FIXME: Diagnose this particular error.
11003f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    }
11013f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor
1102c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    bool IsDependent = false;
1103c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
1104a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    // Don't pass down template parameter lists if this is just a tag
1105a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    // reference.  For example, we don't need the template parameters here:
1106a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    //   template <class T> class A *makeA(T t);
1107a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    MultiTemplateParamsArg TParams;
1108a25c4080a490ea2bab6f54094dd75b19eae83770John McCall    if (TUK != Sema::TUK_Reference && TemplateParams)
1109a25c4080a490ea2bab6f54094dd75b19eae83770John McCall      TParams =
1110a25c4080a490ea2bab6f54094dd75b19eae83770John McCall        MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size());
1111a25c4080a490ea2bab6f54094dd75b19eae83770John McCall
11123f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Declaration or definition of a class type
11139a34edb710917798aa30263374f624f13b594605John McCall    TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc,
11147f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                       SS, Name, NameLoc, attrs.getList(), AS,
1115a25c4080a490ea2bab6f54094dd75b19eae83770John McCall                                       TParams, Owned, IsDependent, false,
1116a88cefd266c428be33cc06f7e8b00ff8fc97c1ffAbramo Bagnara                                       false, clang::TypeResult());
1117c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
1118c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // If ActOnTag said the type was dependent, try again with the
1119c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // less common call.
11209a34edb710917798aa30263374f624f13b594605John McCall    if (IsDependent) {
11219a34edb710917798aa30263374f624f13b594605John McCall      assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend);
112223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK,
1123193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                                             SS, Name, StartLoc, NameLoc);
11249a34edb710917798aa30263374f624f13b594605John McCall    }
11253f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  }
1126e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1127e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If there is a body, parse it and inform the actions module.
1128f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  if (TUK == Sema::TUK_Definition) {
1129bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    assert(Tok.is(tok::l_brace) ||
1130cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson           (getLang().CPlusPlus && Tok.is(tok::colon)) ||
11318a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson           isCXX0XFinalKeyword());
113207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    if (getLang().CPlusPlus)
1133212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
113407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    else
1135212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
1136e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1137e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1138b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  const char *PrevSpec = 0;
1139b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  unsigned DiagID;
1140b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  bool Result;
1141c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  if (!TypeResult.isInvalid()) {
11420daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara    Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
11430daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                NameLoc.isValid() ? NameLoc : StartLoc,
1144b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall                                PrevSpec, DiagID, TypeResult.get());
1145c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else if (!TagOrTempResult.isInvalid()) {
11460daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara    Result = DS.SetTypeSpecType(TagType, StartLoc,
11470daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                NameLoc.isValid() ? NameLoc : StartLoc,
11480daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara                                PrevSpec, DiagID, TagOrTempResult.get(), Owned);
1149c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else {
1150ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    DS.SetTypeSpecError();
115166e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson    return;
115266e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson  }
11531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1154b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  if (Result)
1155fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
1156193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
11574ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // At this point, we've successfully parsed a class-specifier in 'definition'
11584ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // form (e.g. "struct foo { int x; }".  While we could just return here, we're
11594ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // going to look at what comes after it to improve error recovery.  If an
11604ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // impossible token occurs next, we assume that the programmer forgot a ; at
11614ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // the end of the declaration and recover that way.
11624ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  //
11634ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // This switch enumerates the valid "follow" set for definition.
1164f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  if (TUK == Sema::TUK_Definition) {
1165b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    bool ExpectedSemi = true;
11664ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    switch (Tok.getKind()) {
1167b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    default: break;
11684ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    case tok::semi:               // struct foo {...} ;
116999c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::star:               // struct foo {...} *         P;
117099c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::amp:                // struct foo {...} &         R = ...
117199c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::identifier:         // struct foo {...} V         ;
117299c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::r_paren:            //(struct foo {...} )         {4}
117399c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_cxxscope:     // struct foo {...} a::       b;
117499c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_typename:     // struct foo {...} a         ::b;
117599c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_template_id:  // struct foo {...} a<int>    ::b;
1176c2e1c1af8ffe750b827284f207b9207112c7cc4eChris Lattner    case tok::l_paren:            // struct foo {...} (         x);
117716acfee729e00536af827935ccfcf69be721e462Chris Lattner    case tok::comma:              // __builtin_offsetof(struct foo{...} ,
1178b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      ExpectedSemi = false;
1179b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      break;
1180b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    // Type qualifiers
1181b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_const:           // struct foo {...} const     x;
1182b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_volatile:        // struct foo {...} volatile  x;
1183b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_restrict:        // struct foo {...} restrict  x;
1184b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_inline:          // struct foo {...} inline    foo() {};
118599c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    // Storage-class specifiers
118699c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_static:          // struct foo {...} static    x;
118799c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_extern:          // struct foo {...} extern    x;
118899c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_typedef:         // struct foo {...} typedef   x;
118999c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_register:        // struct foo {...} register  x;
119099c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_auto:            // struct foo {...} auto      x;
119133f992425213f381fc503699b26ee8cf9b60494eDouglas Gregor    case tok::kw_mutable:         // struct foo {...} mutable      x;
1192b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // As shown above, type qualifiers and storage class specifiers absolutely
1193b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // can occur after class specifiers according to the grammar.  However,
1194fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner      // almost no one actually writes code like this.  If we see one of these,
1195b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // it is much more likely that someone missed a semi colon and the
1196b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // type/storage class specifier we're seeing is part of the *next*
1197b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // intended declaration, as in:
1198b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //
1199b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //   struct foo { ... }
1200b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //   typedef int X;
1201b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //
1202b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // We'd really like to emit a missing semicolon error instead of emitting
1203b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // an error on the 'int' saying that you can't have two type specifiers in
1204b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // the same declaration of X.  Because of this, we look ahead past this
1205b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // token to see if it's a type specifier.  If so, we know the code is
1206b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // otherwise invalid, so we can produce the expected semi error.
1207b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      if (!isKnownToBeTypeSpecifier(NextToken()))
1208b3a4e432c90be98c6d918087750397e86d030368Chris Lattner        ExpectedSemi = false;
12094ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      break;
1210193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1211193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam    case tok::r_brace:  // struct bar { struct foo {...} }
12124ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // Missing ';' at end of struct is accepted as an extension in C mode.
1213b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      if (!getLang().CPlusPlus)
1214b3a4e432c90be98c6d918087750397e86d030368Chris Lattner        ExpectedSemi = false;
1215b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      break;
1216b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    }
1217193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1218b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    if (ExpectedSemi) {
12194ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
12204ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner                       TagType == DeclSpec::TST_class ? "class"
12214ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner                       : TagType == DeclSpec::TST_struct? "struct" : "union");
12224ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // Push this token back into the preprocessor and change our current token
12234ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // to ';' so that the rest of the code recovers as though there were an
12244ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // ';' after the definition.
12254ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      PP.EnterToken(Tok);
1226193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      Tok.setKind(tok::semi);
12274ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    }
12284ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  }
1229e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1230e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
12311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
1232e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1233e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-clause : [C++ class.derived]
1234e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ':' base-specifier-list
1235e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier-list:
1236e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier '...'[opt]
1237e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier-list ',' base-specifier '...'[opt]
1238d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseBaseClause(Decl *ClassDecl) {
1239e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  assert(Tok.is(tok::colon) && "Not a base clause");
1240e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  ConsumeToken();
1241e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1242f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Build up an array of parsed base specifiers.
1243ca0408fb49c1370430672acf2d770b7151cf71deJohn McCall  llvm::SmallVector<CXXBaseSpecifier *, 8> BaseInfo;
1244f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
1245e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  while (true) {
1246e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Parse a base-specifier.
1247f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    BaseResult Result = ParseBaseSpecifier(ClassDecl);
12485ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor    if (Result.isInvalid()) {
1249e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Skip the rest of this base specifier, up until the comma or
1250e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // opening brace.
1251f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      SkipUntil(tok::comma, tok::l_brace, true, true);
1252f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    } else {
1253f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      // Add this to our array of base specifiers.
12545ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor      BaseInfo.push_back(Result.get());
1255e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
1256e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1257e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // If the next token is a comma, consume it and keep reading
1258e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // base-specifiers.
1259e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (Tok.isNot(tok::comma)) break;
12601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1261e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Consume the comma.
1262e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
1263e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1264f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
1265f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Attach the base specifiers
1266beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad  Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size());
1267e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1268e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1269e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
1270e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example:
1271e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///    class foo : public bar, virtual private baz {
1272e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers.
1273e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1274e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier: [C++ class.derived]
1275e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ::[opt] nested-name-specifier[opt] class-name
1276e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt]
1277e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                        class-name
1278e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
1279e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                        class-name
1280d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {
1281e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  bool IsVirtual = false;
1282e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation StartLoc = Tok.getLocation();
1283e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1284e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword.
1285e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
1286e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
1287e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
1288e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1289e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1290e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse an (optional) access specifier.
1291e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  AccessSpecifier Access = getAccessSpecifierIfPresent();
129292f883177b162928a8e632e4e3b93fafd2b26072John McCall  if (Access != AS_none)
1293e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
12941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1295e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword (again!), in case it came after the
1296e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // access specifier.
1297e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
1298e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SourceLocation VirtualLoc = ConsumeToken();
1299e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (IsVirtual) {
1300e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Complain about duplicate 'virtual'
13011ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner      Diag(VirtualLoc, diag::err_dup_virtual)
1302849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor        << FixItHint::CreateRemoval(VirtualLoc);
1303e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
1304e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1305e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
1306e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1307e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1308eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse optional '::' and optional nested-name-specifier.
1309eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  CXXScopeSpec SS;
1310b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
1311e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1312e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // The location of the base class itself.
1313e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation BaseLoc = Tok.getLocation();
131442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
131542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Parse the class-name.
13167f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceLocation EndLocation;
1317059101f922de6eb765601459925f4c8914420b23Douglas Gregor  TypeResult BaseType = ParseClassName(EndLocation, SS);
131831a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor  if (BaseType.isInvalid())
131942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor    return true;
13201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1321f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // Parse the optional ellipsis (for a pack expansion). The ellipsis is
1322f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // actually part of the base-specifier-list grammar productions, but we
1323f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  // parse it here for convenience.
1324f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  SourceLocation EllipsisLoc;
1325f90b27ad077c3339b62befc892382845339f9490Douglas Gregor  if (Tok.is(tok::ellipsis))
1326f90b27ad077c3339b62befc892382845339f9490Douglas Gregor    EllipsisLoc = ConsumeToken();
1327f90b27ad077c3339b62befc892382845339f9490Douglas Gregor
13281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Find the complete source range for the base-specifier.
13297f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceRange Range(StartLoc, EndLocation);
13301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1331e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Notify semantic analysis that we have parsed a complete
1332e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // base-specifier.
1333a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl  return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
1334f90b27ad077c3339b62befc892382845339f9490Douglas Gregor                                    BaseType.get(), BaseLoc, EllipsisLoc);
1335e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1336e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1337e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is
1338e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier.
1339e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1340e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       access-specifier: [C++ class.derived]
1341e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'private'
1342e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'protected'
1343e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'public'
13441eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAccessSpecifier Parser::getAccessSpecifierIfPresent() const {
1345e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  switch (Tok.getKind()) {
1346e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  default: return AS_none;
1347e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_private: return AS_private;
1348e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_protected: return AS_protected;
1349e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_public: return AS_public;
1350e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1351e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
13524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1353d33133cdc1af466f9c276249b2621be03867888bEli Friedmanvoid Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
1354d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall                                             Decl *ThisDecl) {
1355d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // We just declared a member function. If this member function
1356d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // has any default arguments, we'll need to parse them later.
1357d33133cdc1af466f9c276249b2621be03867888bEli Friedman  LateParsedMethodDeclaration *LateMethod = 0;
13581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  DeclaratorChunk::FunctionTypeInfo &FTI
1359075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara    = DeclaratorInfo.getFunctionTypeInfo();
1360d33133cdc1af466f9c276249b2621be03867888bEli Friedman  for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
1361d33133cdc1af466f9c276249b2621be03867888bEli Friedman    if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
1362d33133cdc1af466f9c276249b2621be03867888bEli Friedman      if (!LateMethod) {
1363d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Push this method onto the stack of late-parsed method
1364d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // declarations.
1365d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);
1366d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
136723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        LateMethod->TemplateScope = getCurScope()->isTemplateParamScope();
1368d33133cdc1af466f9c276249b2621be03867888bEli Friedman
1369d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Add all of the parameters prior to this one (they don't
1370d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // have default arguments).
1371d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateMethod->DefaultArgs.reserve(FTI.NumArgs);
1372d33133cdc1af466f9c276249b2621be03867888bEli Friedman        for (unsigned I = 0; I < ParamIdx; ++I)
1373d33133cdc1af466f9c276249b2621be03867888bEli Friedman          LateMethod->DefaultArgs.push_back(
13748f8210c47797f013e0fb24a26f9c4751b10783feDouglas Gregor                             LateParsedDefaultArgument(FTI.ArgInfo[I].Param));
1375d33133cdc1af466f9c276249b2621be03867888bEli Friedman      }
1376d33133cdc1af466f9c276249b2621be03867888bEli Friedman
1377d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // Add this parameter to the list of parameters (it or may
1378d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // not have a default argument).
1379d33133cdc1af466f9c276249b2621be03867888bEli Friedman      LateMethod->DefaultArgs.push_back(
1380d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
1381d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                  FTI.ArgInfo[ParamIdx].DefaultArgTokens));
1382d33133cdc1af466f9c276249b2621be03867888bEli Friedman    }
1383d33133cdc1af466f9c276249b2621be03867888bEli Friedman  }
1384d33133cdc1af466f9c276249b2621be03867888bEli Friedman}
1385d33133cdc1af466f9c276249b2621be03867888bEli Friedman
13861f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// isCXX0XVirtSpecifier - Determine whether the next token is a C++0x
13871f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier.
13881f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
13891f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier:
13901f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         override
13911f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         final
1392cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders CarlssonVirtSpecifiers::Specifier Parser::isCXX0XVirtSpecifier() const {
1393ce93a7cee6c0ea979c12b278771a79c4d6a37fc0Anders Carlsson  if (!getLang().CPlusPlus)
1394cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson    return VirtSpecifiers::VS_None;
1395cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
1396b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  if (Tok.is(tok::identifier)) {
1397b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    IdentifierInfo *II = Tok.getIdentifierInfo();
13981f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
13997eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    // Initialize the contextual keywords.
14007eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    if (!Ident_final) {
14017eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson      Ident_final = &PP.getIdentifierTable().get("final");
14027eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson      Ident_override = &PP.getIdentifierTable().get("override");
14037eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson    }
14047eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson
1405b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (II == Ident_override)
1406b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return VirtSpecifiers::VS_Override;
14071f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
1408b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (II == Ident_final)
1409b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return VirtSpecifiers::VS_Final;
1410b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  }
1411b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
1412b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  return VirtSpecifiers::VS_None;
14131f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson}
14141f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
14151f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// ParseOptionalCXX0XVirtSpecifierSeq - Parse a virt-specifier-seq.
14161f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
14171f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier-seq:
14181f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier
14191f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier-seq virt-specifier
1420b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlssonvoid Parser::ParseOptionalCXX0XVirtSpecifierSeq(VirtSpecifiers &VS) {
1421b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  while (true) {
1422cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson    VirtSpecifiers::Specifier Specifier = isCXX0XVirtSpecifier();
1423b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    if (Specifier == VirtSpecifiers::VS_None)
1424b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      return;
1425b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
1426b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    // C++ [class.mem]p8:
1427b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    //   A virt-specifier-seq shall contain at most one of each virt-specifier.
1428cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson    const char *PrevSpec = 0;
142946127a96b6dd6b93aa18d5f7a55bc2db8b52a2c9Anders Carlsson    if (VS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec))
1430b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson      Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier)
1431b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson        << PrevSpec
1432b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson        << FixItHint::CreateRemoval(Tok.getLocation());
1433b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson
1434ce93a7cee6c0ea979c12b278771a79c4d6a37fc0Anders Carlsson    if (!getLang().CPlusPlus0x)
1435ce93a7cee6c0ea979c12b278771a79c4d6a37fc0Anders Carlsson      Diag(Tok.getLocation(), diag::ext_override_control_keyword)
1436ce93a7cee6c0ea979c12b278771a79c4d6a37fc0Anders Carlsson        << VirtSpecifiers::getSpecifierName(Specifier);
1437b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    ConsumeToken();
1438b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson  }
14391f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson}
14401f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
14418a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson/// isCXX0XFinalKeyword - Determine whether the next token is a C++0x
14428a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson/// contextual 'final' keyword.
14438a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlssonbool Parser::isCXX0XFinalKeyword() const {
1444ce93a7cee6c0ea979c12b278771a79c4d6a37fc0Anders Carlsson  if (!getLang().CPlusPlus)
14458a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    return false;
1446cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
14478a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  if (!Tok.is(tok::identifier))
14488a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    return false;
1449cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
14508a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  // Initialize the contextual keywords.
14518a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  if (!Ident_final) {
14528a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    Ident_final = &PP.getIdentifierTable().get("final");
14538a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson    Ident_override = &PP.getIdentifierTable().get("override");
1454cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson  }
14558a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson
14568a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson  return Tok.getIdentifierInfo() == Ident_final;
1457cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson}
1458cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
14594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
14604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
14614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declaration:
14624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         decl-specifier-seq[opt] member-declarator-list[opt] ';'
14634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         function-definition ';'[opt]
14644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
14654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         using-declaration                                            [TODO]
1466511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration
14675aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson///         template-declaration
1468bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU]   '__extension__' member-declaration
14694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
14704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator-list:
14714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator
14724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator-list ',' member-declarator
14734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
14744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator:
14751f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         declarator virt-specifier-seq[opt] pure-specifier[opt]
14764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         declarator constant-initializer[opt]
14774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         identifier[opt] ':' constant-expression
14784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
14791f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier-seq:
14801f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier
14811f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         virt-specifier-seq virt-specifier
14821f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
14831f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///       virt-specifier:
14841f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         override
14851f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         final
14861f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///         new
14871f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson///
1488e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl///       pure-specifier:
14894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '= 0'
14904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
14914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       constant-initializer:
14924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '=' constant-expression
14934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
149437b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregorvoid Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
1495c9068d7dd94d439cec66c421115d15303e481025John McCall                                       const ParsedTemplateInfo &TemplateInfo,
1496c9068d7dd94d439cec66c421115d15303e481025John McCall                                       ParsingDeclRAIIObject *TemplateDiags) {
14978a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor  if (Tok.is(tok::at)) {
14988a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    if (getLang().ObjC1 && NextToken().isObjCAtKeyword(tok::objc_defs))
14998a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor      Diag(Tok, diag::err_at_defs_cxx);
15008a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    else
15018a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor      Diag(Tok, diag::err_at_in_class);
15028a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor
15038a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    ConsumeToken();
15048a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    SkipUntil(tok::r_brace);
15058a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor    return;
15068a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor  }
15078a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor
150860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  // Access declarations.
150960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  if (!TemplateInfo.Kind &&
151060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) &&
15119ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall      !TryAnnotateCXXScopeToken() &&
151260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      Tok.is(tok::annot_cxxscope)) {
151360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    bool isAccessDecl = false;
151460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    if (NextToken().is(tok::identifier))
151560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      isAccessDecl = GetLookAheadToken(2).is(tok::semi);
151660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    else
151760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      isAccessDecl = NextToken().is(tok::kw_operator);
151860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
151960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    if (isAccessDecl) {
152060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // Collect the scope specifier token we annotated earlier.
152160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      CXXScopeSpec SS;
1522b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
152360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
152460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // Try to parse an unqualified-id.
152560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      UnqualifiedId Name;
1526b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), Name)) {
152760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        SkipUntil(tok::semi);
152860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        return;
152960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      }
153060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
153160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // TODO: recover from mistakenly-qualified operator declarations.
153260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      if (ExpectAndConsume(tok::semi,
153360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           diag::err_expected_semi_after,
153460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           "access declaration",
153560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           tok::semi))
153660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        return;
153760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
153823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      Actions.ActOnUsingDeclaration(getCurScope(), AS,
153960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    false, SourceLocation(),
154060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    SS, Name,
154160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    /* AttrList */ 0,
154260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    /* IsTypeName */ false,
154360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    SourceLocation());
154460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      return;
154560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    }
154660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  }
154760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
1548511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  // static_assert-declaration
1549c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne  if (Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) {
155037b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    // FIXME: Check for templates
155197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
155297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    ParseStaticAssertDeclaration(DeclEnd);
1553682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1554682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
15551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1556682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  if (Tok.is(tok::kw_template)) {
15571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(!TemplateInfo.TemplateParams &&
155837b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor           "Nested template improperly parsed?");
155997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
15601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd,
15614d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                         AS);
1562682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1563682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
15645aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson
1565bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  // Handle:  member-declaration ::= '__extension__' member-declaration
1566bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  if (Tok.is(tok::kw___extension__)) {
1567bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    // __extension__ silences extension warnings in the subexpression.
1568bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
1569bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ConsumeToken();
1570c9068d7dd94d439cec66c421115d15303e481025John McCall    return ParseCXXClassMemberDeclaration(AS, TemplateInfo, TemplateDiags);
1571bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  }
15729cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
15734ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it
15744ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // is a bitfield.
1575a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner  ColonProtectionRAIIObject X(*this);
1576193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
15770b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributesWithRange attrs(AttrFactory);
1578bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // Optional C++0x attribute-specifier
15797f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseCXX0XAttributes(attrs);
15807f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseMicrosoftAttributes(attrs);
1581bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
15829cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_using)) {
15837f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    ProhibitAttributes(attrs);
15841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15859cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    // Eat 'using'.
15869cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SourceLocation UsingLoc = ConsumeToken();
15879cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
15889cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    if (Tok.is(tok::kw_namespace)) {
15899cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      Diag(UsingLoc, diag::err_using_namespace_in_class);
15909cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SkipUntil(tok::semi, true, true);
1591ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    } else {
15929cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SourceLocation DeclEnd;
15933e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith      // Otherwise, it must be a using-declaration or an alias-declaration.
159478b810559d89e996e00684335407443936ce34a1John McCall      ParseUsingDeclaration(Declarator::MemberContext, TemplateInfo,
159578b810559d89e996e00684335407443936ce34a1John McCall                            UsingLoc, DeclEnd, AS);
15969cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    }
15979cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return;
15989cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
15999cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
16004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // decl-specifier-seq:
16014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Parse the common declaration-specifiers piece.
1602c9068d7dd94d439cec66c421115d15303e481025John McCall  ParsingDeclSpec DS(*this, TemplateDiags);
16037f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  DS.takeAttributesFrom(attrs);
160437b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor  ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class);
16054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1606f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  MultiTemplateParamsArg TemplateParams(Actions,
1607dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
1608dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
1609dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
16104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::semi)) {
16114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
1612d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decl *TheDecl =
16130f4be74ff0273e505d383f89174ef539828424edChandler Carruth      Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS, TemplateParams);
1614c9068d7dd94d439cec66c421115d15303e481025John McCall    DS.complete(TheDecl);
161567d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    return;
16164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
161707952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
161854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext);
16194867347e82648d3baf09524b98b09c297a5a198fNico Weber  VirtSpecifiers VS;
16206a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet  ExprResult Init;
16214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
16223a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis  if (Tok.isNot(tok::colon)) {
1623a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner    // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
1624a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner    ColonProtectionRAIIObject X(*this);
1625a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner
16263a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Parse the first declarator.
16273a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    ParseDeclarator(DeclaratorInfo);
16283a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Error parsing the declarator?
162910bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor    if (!DeclaratorInfo.hasName()) {
16303a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      // If so, skip until the semi-colon or a }.
1631d941fa4ff0d0d64b5a541dbd4f99693bff7f6e8dSebastian Redl      SkipUntil(tok::r_brace, true, true);
16323a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (Tok.is(tok::semi))
16333a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeToken();
1634682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
16354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
16364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
16374867347e82648d3baf09524b98b09c297a5a198fNico Weber    ParseOptionalCXX0XVirtSpecifierSeq(VS);
16384867347e82648d3baf09524b98b09c297a5a198fNico Weber
16391b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson    // If attributes exist after the declarator, but before an '{', parse them.
16407f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseGNUAttributes(DeclaratorInfo);
16411b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson
16426a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    // MSVC permits pure specifier on inline functions declared at class scope.
16436a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    // Hence check for =0 before checking for function definition.
16446a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    if (getLang().Microsoft && Tok.is(tok::equal) &&
16456a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        DeclaratorInfo.isFunctionDeclarator() &&
16466a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        NextToken().is(tok::numeric_constant)) {
16476a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet      ConsumeToken();
16486a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet      Init = ParseInitializer();
16496a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet      if (Init.isInvalid())
16506a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet        SkipUntil(tok::comma, true, true);
16516a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet    }
16526a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet
1653e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    bool IsDefinition = false;
16543a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // function-definition:
1655e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    if (Tok.is(tok::l_brace)) {
1656e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      IsDefinition = true;
1657e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    } else if (DeclaratorInfo.isFunctionDeclarator()) {
1658e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
1659e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        IsDefinition = true;
1660e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      } else if (Tok.is(tok::equal)) {
1661e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        const Token &KW = NextToken();
1662e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        if (KW.is(tok::kw_default) || KW.is(tok::kw_delete))
1663e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt          IsDefinition = true;
1664e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      }
1665e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    }
1666e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
1667e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    if (IsDefinition) {
16683a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (!DeclaratorInfo.isFunctionDeclarator()) {
16693a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        Diag(Tok, diag::err_func_def_no_params);
16703a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
16713a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        SkipUntil(tok::r_brace, true);
16729ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor
16739ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        // Consume the optional ';'
16749ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        if (Tok.is(tok::semi))
16759ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor          ConsumeToken();
1676682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
16773a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
16783a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis
16793a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
16803a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        Diag(Tok, diag::err_function_declared_typedef);
16813a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // This recovery skips the entire function body. It would be nice
16823a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // to simply call ParseCXXInlineMethodDef() below, however Sema
16833a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // assumes the declarator represents a function, not a typedef.
16843a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
16853a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        SkipUntil(tok::r_brace, true);
16869ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor
16879ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        // Consume the optional ';'
16889ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        if (Tok.is(tok::semi))
16899ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor          ConsumeToken();
1690682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
16913a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
16924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
16936a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet      ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo, VS, Init);
1694e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
1695e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      // Consume the ';' - it's optional unless we have a delete or default
1696e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      if (Tok.is(tok::semi)) {
16979ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor        ConsumeToken();
1698e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      }
16999ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor
1700682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
17013a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    }
17024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
17034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
17044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // member-declarator-list:
17054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator
17064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator-list ',' member-declarator
17074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1708d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  llvm::SmallVector<Decl *, 8> DeclsInGroup;
170960d7b3a319d84d688752be3870615ac0f111fb16John McCall  ExprResult BitfieldSize;
17104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
17114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  while (1) {
17124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // member-declarator:
17134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   declarator pure-specifier[opt]
17144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   declarator constant-initializer[opt]
17154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   identifier[opt] ':' constant-expression
17164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::colon)) {
17174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
17180e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      BitfieldSize = ParseConstantExpression();
17190e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      if (BitfieldSize.isInvalid())
17204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        SkipUntil(tok::comma, true, true);
17214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
17221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1723b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson    ParseOptionalCXX0XVirtSpecifierSeq(VS);
17241f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson
17254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // pure-specifier:
17264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   '= 0'
17274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //
17284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // constant-initializer:
17294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   '=' constant-expression
1730e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //
1731e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    // defaulted/deleted function-definition:
1732e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //   '=' 'default'                          [TODO]
1733e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //   '=' 'delete'
17344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::equal)) {
17354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
173637bf9d2bb74944c9d9a52522412bc077629977f1Anders Carlsson      if (Tok.is(tok::kw_delete)) {
1737e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        if (DeclaratorInfo.isFunctionDeclarator())
1738e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt          Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
1739e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt            << 1 /* delete */;
1740e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        else
1741e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt          Diag(ConsumeToken(), diag::err_deleted_non_function);
1742fe2695eec167b28578825576863228f86b392f24Sean Hunt      } else if (Tok.is(tok::kw_default)) {
1743e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        if (DeclaratorInfo.isFunctionDeclarator())
1744e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt          Diag(Tok, diag::err_default_delete_in_multiple_declaration)
1745e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt            << 1 /* delete */;
1746e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        else
1747e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt          Diag(ConsumeToken(), diag::err_default_special_members);
1748e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl      } else {
1749e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        Init = ParseInitializer();
1750e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        if (Init.isInvalid())
1751e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl          SkipUntil(tok::comma, true, true);
1752e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl      }
17534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
17544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1755e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    // If a simple-asm-expr is present, parse it.
1756e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    if (Tok.is(tok::kw_asm)) {
1757e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      SourceLocation Loc;
175860d7b3a319d84d688752be3870615ac0f111fb16John McCall      ExprResult AsmLabel(ParseSimpleAsm(&Loc));
1759e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      if (AsmLabel.isInvalid())
1760e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner        SkipUntil(tok::comma, true, true);
1761e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner
1762e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      DeclaratorInfo.setAsmLabel(AsmLabel.release());
1763e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      DeclaratorInfo.SetRangeEnd(Loc);
1764e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    }
1765e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner
17664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If attributes exist after the declarator, parse them.
17677f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseGNUAttributes(DeclaratorInfo);
17684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
176907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // NOTE: If Sema is the Action module and declarator is an instance field,
1770682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    // this call will *not* return the created decl; It will return null.
177107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // See Sema::ActOnCXXMemberDeclarator for details.
177267d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall
1773d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall    Decl *ThisDecl = 0;
177467d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    if (DS.isFriendSpecified()) {
1775bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall      // TODO: handle initializers, bitfields, 'delete'
177623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo,
1777bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall                                                 /*IsDefinition*/ false,
1778bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall                                                 move(TemplateParams));
177937b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    } else {
178023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor      ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS,
178167d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  DeclaratorInfo,
178237b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor                                                  move(TemplateParams),
178367d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  BitfieldSize.release(),
1784e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt                                                  VS, Init.release(), false);
178537b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    }
1786682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    if (ThisDecl)
1787682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      DeclsInGroup.push_back(ThisDecl);
17884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
178972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    if (DeclaratorInfo.isFunctionDeclarator() &&
17901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        DeclaratorInfo.getDeclSpec().getStorageClassSpec()
179172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor          != DeclSpec::SCS_typedef) {
1792d33133cdc1af466f9c276249b2621be03867888bEli Friedman      HandleMemberFunctionDefaultArgs(DeclaratorInfo, ThisDecl);
179372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    }
179472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor
179554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    DeclaratorInfo.complete(ThisDecl);
179654abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
17974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If we don't have a comma, it is either the end of the list (a ';')
17984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // or an error, bail out.
17994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.isNot(tok::comma))
18004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
18011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Consume the comma.
18034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
18041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Parse the next declarator.
18064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    DeclaratorInfo.clear();
18074867347e82648d3baf09524b98b09c297a5a198fNico Weber    VS.clear();
180815faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl    BitfieldSize = 0;
180915faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl    Init = 0;
18101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Attributes are only allowed on the second declarator.
18127f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    MaybeParseGNUAttributes(DeclaratorInfo);
18134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
18143a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    if (Tok.isNot(tok::colon))
18153a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      ParseDeclarator(DeclaratorInfo);
18164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
18174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1818ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner  if (ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
1819ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    // Skip to end of block or statement.
1820ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    SkipUntil(tok::r_brace, true, true);
1821ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    // If we stopped at a ';', eat it.
1822ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    if (Tok.is(tok::semi)) ConsumeToken();
1823682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
18244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
18254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
182623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup.data(),
1827ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner                                  DeclsInGroup.size());
18284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
18294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
18304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition.
18314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
18324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-specification:
18334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declaration member-specification[opt]
18344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         access-specifier ':' member-specification[opt]
18354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
18364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidisvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
1837d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall                                         unsigned TagType, Decl *TagDecl) {
183831fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta  assert((TagType == DeclSpec::TST_struct ||
18394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis         TagType == DeclSpec::TST_union  ||
184031fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta         TagType == DeclSpec::TST_class) && "Invalid TagType!");
18414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1842f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc,
1843f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall                                      "parsing struct/union/class body");
18441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
184526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  // Determine whether this is a non-nested class. Note that local
184626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  // classes are *not* considered to be nested classes.
184726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  bool NonNestedClass = true;
184826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  if (!ClassStack.empty()) {
184923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    for (const Scope *S = getCurScope(); S; S = S->getParent()) {
185026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      if (S->isClassScope()) {
185126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // We're inside a class scope, so this is a nested class.
185226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        NonNestedClass = false;
185326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        break;
185426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      }
185526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor
185626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      if ((S->getFlags() & Scope::FnScope)) {
185726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // If we're in a function or function template declared in the
185826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // body of a class, then this is a local class rather than a
185926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // nested class.
186026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        const Scope *Parent = S->getParent();
186126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        if (Parent->isTemplateParamScope())
186226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor          Parent = Parent->getParent();
186326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        if (Parent->isClassScope())
186426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor          break;
186526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      }
186626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor    }
186726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  }
18684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
18694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Enter a scope for the class.
18703218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
18714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
18726569d68745c8213709740337d2be52b031384f58Douglas Gregor  // Note that we are parsing a new (potentially-nested) class definition.
187326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass);
18746569d68745c8213709740337d2be52b031384f58Douglas Gregor
1875ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  if (TagDecl)
187623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
1877bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
1878b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  SourceLocation FinalLoc;
1879b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson
1880b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  // Parse the optional 'final' keyword.
1881b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  if (getLang().CPlusPlus && Tok.is(tok::identifier)) {
1882b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson    IdentifierInfo *II = Tok.getIdentifierInfo();
1883b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson
1884b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson    // Initialize the contextual keywords.
1885b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson    if (!Ident_final) {
1886b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson      Ident_final = &PP.getIdentifierTable().get("final");
1887b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson      Ident_override = &PP.getIdentifierTable().get("override");
1888b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson    }
1889b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson
1890b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson    if (II == Ident_final)
1891b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson      FinalLoc = ConsumeToken();
1892b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson
1893b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson    if (!getLang().CPlusPlus0x)
1894b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson      Diag(FinalLoc, diag::ext_override_control_keyword) << "final";
1895b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson  }
1896cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson
1897bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  if (Tok.is(tok::colon)) {
1898bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    ParseBaseClause(TagDecl);
1899bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
1900bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    if (!Tok.is(tok::l_brace)) {
1901bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall      Diag(Tok, diag::err_expected_lbrace_after_base_specifiers);
1902db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall
1903db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall      if (TagDecl)
190423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor        Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);
1905bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall      return;
1906bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    }
1907bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  }
1908bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
1909bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  assert(Tok.is(tok::l_brace));
1910bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
1911bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  SourceLocation LBraceLoc = ConsumeBrace();
1912bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
191342a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
19142c3ee54e51d835a35bbf781c69e17f39e2ba0480Anders Carlsson    Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc,
1915dfc2f1035d23e294b298766a3cf51dfe249d53a2Anders Carlsson                                            LBraceLoc);
1916f9368159334ff86ea5fa367225c1a580977f3b03John McCall
19174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // C++ 11p3: Members of a class defined with the keyword class are private
19184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // by default. Members of a class defined with the keywords struct or union
19194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // are public by default.
19204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  AccessSpecifier CurAS;
19214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (TagType == DeclSpec::TST_class)
19224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_private;
19234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  else
19244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_public;
19254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
192607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  SourceLocation RBraceLoc;
192707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  if (TagDecl) {
192807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    // While we still have something to read, read the member-declarations.
192907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
193007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Each iteration of this loop reads one member-declaration.
193107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor
193207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Check for extraneous top-level semicolon.
193307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      if (Tok.is(tok::semi)) {
193407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        Diag(Tok, diag::ext_extra_struct_semi)
193507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor          << DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
193607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor          << FixItHint::CreateRemoval(Tok.getLocation());
193707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        ConsumeToken();
193807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        continue;
193907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      }
19401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
194107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      AccessSpecifier AS = getAccessSpecifierIfPresent();
194207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      if (AS != AS_none) {
194307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        // Current token is a C++ access specifier.
194407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        CurAS = AS;
194507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        SourceLocation ASLoc = Tok.getLocation();
194607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        ConsumeToken();
194707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        if (Tok.is(tok::colon))
194807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor          Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
194907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        else
195007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor          Diag(Tok, diag::err_expected_colon);
195107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        ConsumeToken();
195207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor        continue;
195307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      }
19544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
195507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // FIXME: Make sure we don't have a template here.
19564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
195707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      // Parse all the comma separated declarators.
195807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor      ParseCXXClassMemberDeclaration(CurAS);
195907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    }
19601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
196107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
196207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  } else {
196307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor    SkipUntil(tok::r_brace, false, false);
19644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
19651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // If attributes exist after class contents, parse them.
19670b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall  ParsedAttributes attrs(AttrFactory);
19687f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  MaybeParseGNUAttributes(attrs);
19694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
197042a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
197123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
197242a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall                                              LBraceLoc, RBraceLoc,
19737f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                              attrs.getList());
19744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
19754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // C++ 9.2p2: Within the class member-specification, the class is regarded as
19764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // complete within function bodies, default arguments,
19774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // exception-specifications, and constructor ctor-initializers (including
19784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // such things in nested classes).
19794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //
198072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor  // FIXME: Only function bodies and constructor ctor-initializers are
198172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor  // parsed correctly, fix the rest.
198207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor  if (TagDecl && NonNestedClass) {
19834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // We are not inside a nested class. This class and its nested classes
198472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    // are complete and we can parse the delayed portions of method
198572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    // declarations and the lexed inline method definitions.
1986e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor    SourceLocation SavedPrevTokLocation = PrevTokLocation;
19876569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDeclarations(getCurrentClass());
19886569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDefs(getCurrentClass());
1989e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor    PrevTokLocation = SavedPrevTokLocation;
19904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
19914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
199242a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
199323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, RBraceLoc);
1994db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall
19954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Leave the class scope.
19966569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingDef.Pop();
19978935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ClassScope.Exit();
19984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
19997ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
20007ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer,
20017ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a
20027ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers
20037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below:
20047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
20057ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code
20067ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { };
20077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base {
20087ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   int x;
20097ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   float f;
20107ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public:
20117ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   Derived(float f) : Base(), x(17), f(f) { }
20127ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// };
20137ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode
20147ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
20151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  ctor-initializer:
20161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///          ':' mem-initializer-list
20177ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
20181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  mem-initializer-list:
20193fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor///          mem-initializer ...[opt]
20203fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor///          mem-initializer ...[opt] , mem-initializer-list
2021d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {
20227ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
20237ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
202428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  // Poison the SEH identifiers so they are flagged as illegal in constructor initializers
202528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley  PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true);
20267ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation ColonLoc = ConsumeToken();
20271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2028cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt  llvm::SmallVector<CXXCtorInitializer*, 4> MemInitializers;
20299db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  bool AnyErrors = false;
2030193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
20317ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  do {
20320133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    if (Tok.is(tok::code_completion)) {
20330133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      Actions.CodeCompleteConstructorInitializer(ConstructorDecl,
20340133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor                                                 MemInitializers.data(),
20350133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor                                                 MemInitializers.size());
20360133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      ConsumeCodeCompletionToken();
20370133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    } else {
20380133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
20390133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      if (!MemInit.isInvalid())
20400133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor        MemInitializers.push_back(MemInit.get());
20410133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor      else
20420133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor        AnyErrors = true;
20430133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor    }
20440133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor
20457ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    if (Tok.is(tok::comma))
20467ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      ConsumeToken();
20477ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    else if (Tok.is(tok::l_brace))
20487ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
2049b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor    // If the next token looks like a base or member initializer, assume that
2050b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor    // we're just missing a comma.
2051751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor    else if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) {
2052751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor      SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);
2053751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor      Diag(Loc, diag::err_ctor_init_missing_comma)
2054751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor        << FixItHint::CreateInsertion(Loc, ", ");
2055751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor    } else {
20567ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      // Skip over garbage, until we get to '{'.  Don't eat the '{'.
2057d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl      Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
20587ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      SkipUntil(tok::l_brace, true, true);
20597ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
20607ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    }
20617ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  } while (true);
20627ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
20631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc,
20649db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                               MemInitializers.data(), MemInitializers.size(),
20659db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                               AnyErrors);
20667ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
20677ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
20687ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is
20697ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one
20707ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See
20717ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example.
20727ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
20737ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer:
20747ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         mem-initializer-id '(' expression-list[opt] ')'
20751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
20767ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id:
20777ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         '::'[opt] nested-name-specifier[opt] class-name
20787ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         identifier
2079d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {
2080bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  // parse '::'[opt] nested-name-specifier[opt]
2081bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  CXXScopeSpec SS;
2082b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false);
2083b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall  ParsedType TemplateTypeTy;
2084961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (Tok.is(tok::annot_template_id)) {
2085961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    TemplateIdAnnotation *TemplateId
2086961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
2087d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor    if (TemplateId->Kind == TNK_Type_template ||
2088d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor        TemplateId->Kind == TNK_Dependent_template_name) {
2089059101f922de6eb765601459925f4c8914420b23Douglas Gregor      AnnotateTemplateIdTokenAsType();
2090961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
2091b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall      TemplateTypeTy = getTypeAnnotation(Tok);
2092961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    }
2093961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  }
2094961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (!TemplateTypeTy && Tok.isNot(tok::identifier)) {
20951ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_member_or_base_name);
20967ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
20977ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
20981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20997ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Get the identifier. This may be a member name or a class name,
21007ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // but we'll let the semantic analysis determine which it is.
2101961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  IdentifierInfo *II = Tok.is(tok::identifier) ? Tok.getIdentifierInfo() : 0;
21027ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation IdLoc = ConsumeToken();
21037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
21047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Parse the '('.
21057ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  if (Tok.isNot(tok::l_paren)) {
21061ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen);
21077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
21087ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
21097ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation LParenLoc = ConsumeParen();
21107ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
21117ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Parse the optional expression-list.
2112a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl  ExprVector ArgExprs(Actions);
21137ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  CommaLocsTy CommaLocs;
21147ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
21157ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    SkipUntil(tok::r_paren);
21167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
21177ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
21187ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
21197ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
21207ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
21213fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor  SourceLocation EllipsisLoc;
21223fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor  if (Tok.is(tok::ellipsis))
21233fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor    EllipsisLoc = ConsumeToken();
21243fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor
212523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
2126961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian                                     TemplateTypeTy, IdLoc,
2127a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl                                     LParenLoc, ArgExprs.take(),
21283fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor                                     ArgExprs.size(), RParenLoc,
21293fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor                                     EllipsisLoc);
21307ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
21310fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
21327acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// \brief Parse a C++ exception-specification if present (C++0x [except.spec]).
21330fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
2134a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       exception-specification:
21357acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         dynamic-exception-specification
21367acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         noexcept-specification
21377acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///
21387acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///       noexcept-specification:
21397acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         'noexcept'
21407acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///         'noexcept' '(' constant-expression ')'
21417acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType
21427acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlParser::MaybeParseExceptionSpecification(SourceRange &SpecificationRange,
21437acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                    llvm::SmallVectorImpl<ParsedType> &DynamicExceptions,
21447acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                    llvm::SmallVectorImpl<SourceRange> &DynamicExceptionRanges,
21457acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                    ExprResult &NoexceptExpr) {
21467acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  ExceptionSpecificationType Result = EST_None;
21477acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
21487acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // See if there's a dynamic specification.
21497acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.is(tok::kw_throw)) {
21507acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Result = ParseDynamicExceptionSpecification(SpecificationRange,
21517acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                                DynamicExceptions,
21527acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                                DynamicExceptionRanges);
21537acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    assert(DynamicExceptions.size() == DynamicExceptionRanges.size() &&
21547acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl           "Produced different number of exception types and ranges.");
21557acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
21567acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
21577acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // If there's no noexcept specification, we're done.
21587acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.isNot(tok::kw_noexcept))
21597acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    return Result;
21607acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
21617acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // If we already had a dynamic specification, parse the noexcept for,
21627acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  // recovery, but emit a diagnostic and don't store the results.
21637acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SourceRange NoexceptRange;
21647acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  ExceptionSpecificationType NoexceptType = EST_None;
21657acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
21667acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SourceLocation KeywordLoc = ConsumeToken();
21677acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Tok.is(tok::l_paren)) {
21687acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // There is an argument.
21697acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SourceLocation LParenLoc = ConsumeParen();
21707acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptType = EST_ComputedNoexcept;
21717acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptExpr = ParseConstantExpression();
217260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    // The argument must be contextually convertible to bool. We use
217360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    // ActOnBooleanCondition for this purpose.
217460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    if (!NoexceptExpr.isInvalid())
217560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl      NoexceptExpr = Actions.ActOnBooleanCondition(getCurScope(), KeywordLoc,
217660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl                                                   NoexceptExpr.get());
21777acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
21787acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptRange = SourceRange(KeywordLoc, RParenLoc);
21797acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  } else {
21807acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // There is no argument.
21817acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptType = EST_BasicNoexcept;
21827acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    NoexceptRange = SourceRange(KeywordLoc, KeywordLoc);
21837acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
21847acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
21857acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  if (Result == EST_None) {
21867acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SpecificationRange = NoexceptRange;
21877acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Result = NoexceptType;
21887acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
21897acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // If there's a dynamic specification after a noexcept specification,
21907acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    // parse that and ignore the results.
21917acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    if (Tok.is(tok::kw_throw)) {
21927acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
21937acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions,
21947acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                         DynamicExceptionRanges);
21957acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    }
21967acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  } else {
21977acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);
21987acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  }
21997acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
22007acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  return Result;
22017acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl}
22027acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
22037acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// ParseDynamicExceptionSpecification - Parse a C++
22047acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification (C++ [except.spec]).
22057acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///
22067acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl///       dynamic-exception-specification:
2207a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         'throw' '(' type-id-list [opt] ')'
2208a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS]    'throw' '(' '...' ')'
22091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
2210a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       type-id-list:
2211a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor///         type-id ... [opt]
2212a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor///         type-id-list ',' type-id ... [opt]
22130fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
22147acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(
22157acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                  SourceRange &SpecificationRange,
22167acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                  llvm::SmallVectorImpl<ParsedType> &Exceptions,
22177acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl                                  llvm::SmallVectorImpl<SourceRange> &Ranges) {
22180fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  assert(Tok.is(tok::kw_throw) && "expected throw");
22191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22207acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SpecificationRange.setBegin(ConsumeToken());
22211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22220fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  if (!Tok.is(tok::l_paren)) {
22237acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    Diag(Tok, diag::err_expected_lparen_after) << "throw";
22247acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SpecificationRange.setEnd(SpecificationRange.getBegin());
222560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    return EST_DynamicNone;
22260fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
22270fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  SourceLocation LParenLoc = ConsumeParen();
22280fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
2229a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // Parse throw(...), a Microsoft extension that means "this function
2230a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // can throw anything".
2231a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  if (Tok.is(tok::ellipsis)) {
2232a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    SourceLocation EllipsisLoc = ConsumeToken();
2233a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    if (!getLang().Microsoft)
2234a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor      Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
22357acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
22367acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl    SpecificationRange.setEnd(RParenLoc);
223760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl    return EST_MSAny;
2238a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  }
2239a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor
22400fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  // Parse the sequence of type-ids.
2241ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl  SourceRange Range;
22420fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  while (Tok.isNot(tok::r_paren)) {
2243ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    TypeResult Res(ParseTypeName(&Range));
22447acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
2245a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor    if (Tok.is(tok::ellipsis)) {
2246a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      // C++0x [temp.variadic]p5:
2247a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      //   - In a dynamic-exception-specification (15.4); the pattern is a
2248a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      //     type-id.
2249a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      SourceLocation Ellipsis = ConsumeToken();
22507acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl      Range.setEnd(Ellipsis);
2251a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor      if (!Res.isInvalid())
2252a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor        Res = Actions.ActOnPackExpansion(Res.get(), Ellipsis);
2253a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor    }
22547acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl
2255ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    if (!Res.isInvalid()) {
22567dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl      Exceptions.push_back(Res.get());
2257ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl      Ranges.push_back(Range);
2258ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    }
2259a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor
22600fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor    if (Tok.is(tok::comma))
22610fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      ConsumeToken();
22627dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl    else
22630fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      break;
22640fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
22650fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
22667acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl  SpecificationRange.setEnd(MatchRHSPunctuation(tok::r_paren, LParenLoc));
226760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl  return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic;
22680fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor}
22696569d68745c8213709740337d2be52b031384f58Douglas Gregor
2270dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// ParseTrailingReturnType - Parse a trailing return type on a new-style
2271dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// function declaration.
2272dab60ad68a3a98d687305941a3852e793705f945Douglas GregorTypeResult Parser::ParseTrailingReturnType() {
2273dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  assert(Tok.is(tok::arrow) && "expected arrow");
2274dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
2275dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  ConsumeToken();
2276dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
2277dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  // FIXME: Need to suppress declarations when parsing this typename.
2278dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  // Otherwise in this function definition:
2279dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  //
2280dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  //   auto f() -> struct X {}
2281dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  //
2282dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  // struct X is parsed as class definition because of the trailing
2283dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  // brace.
2284dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
2285dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  SourceRange Range;
2286dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor  return ParseTypeName(&Range);
2287dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor}
2288dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor
22896569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief We have just started parsing the definition of a new class,
22906569d68745c8213709740337d2be52b031384f58Douglas Gregor/// so push that class onto our stack of classes that is currently
22916569d68745c8213709740337d2be52b031384f58Douglas Gregor/// being parsed.
2292eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallSema::ParsingClassState
2293eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallParser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass) {
229426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  assert((NonNestedClass || !ClassStack.empty()) &&
22956569d68745c8213709740337d2be52b031384f58Douglas Gregor         "Nested class without outer class");
229626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass));
2297eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  return Actions.PushParsingClass();
22986569d68745c8213709740337d2be52b031384f58Douglas Gregor}
22996569d68745c8213709740337d2be52b031384f58Douglas Gregor
23006569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Deallocate the given parsed class and all of its nested
23016569d68745c8213709740337d2be52b031384f58Douglas Gregor/// classes.
23026569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
2303d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I)
2304d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    delete Class->LateParsedDeclarations[I];
23056569d68745c8213709740337d2be52b031384f58Douglas Gregor  delete Class;
23066569d68745c8213709740337d2be52b031384f58Douglas Gregor}
23076569d68745c8213709740337d2be52b031384f58Douglas Gregor
23086569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Pop the top class of the stack of classes that are
23096569d68745c8213709740337d2be52b031384f58Douglas Gregor/// currently being parsed.
23106569d68745c8213709740337d2be52b031384f58Douglas Gregor///
23116569d68745c8213709740337d2be52b031384f58Douglas Gregor/// This routine should be called when we have finished parsing the
23126569d68745c8213709740337d2be52b031384f58Douglas Gregor/// definition of a class, but have not yet popped the Scope
23136569d68745c8213709740337d2be52b031384f58Douglas Gregor/// associated with the class's definition.
23146569d68745c8213709740337d2be52b031384f58Douglas Gregor///
23156569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \returns true if the class we've popped is a top-level class,
23166569d68745c8213709740337d2be52b031384f58Douglas Gregor/// false otherwise.
2317eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Parser::PopParsingClass(Sema::ParsingClassState state) {
23186569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");
23191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2320eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  Actions.PopParsingClass(state);
2321eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
23226569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingClass *Victim = ClassStack.top();
23236569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.pop();
23246569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (Victim->TopLevelClass) {
23256569d68745c8213709740337d2be52b031384f58Douglas Gregor    // Deallocate all of the nested classes of this class,
23266569d68745c8213709740337d2be52b031384f58Douglas Gregor    // recursively: we don't need to keep any of this information.
23276569d68745c8213709740337d2be52b031384f58Douglas Gregor    DeallocateParsedClasses(Victim);
23286569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
23291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
23306569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Missing top-level class?");
23316569d68745c8213709740337d2be52b031384f58Douglas Gregor
2332d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (Victim->LateParsedDeclarations.empty()) {
23336569d68745c8213709740337d2be52b031384f58Douglas Gregor    // The victim is a nested class, but we will not need to perform
23346569d68745c8213709740337d2be52b031384f58Douglas Gregor    // any processing after the definition of this class since it has
23356569d68745c8213709740337d2be52b031384f58Douglas Gregor    // no members whose handling was delayed. Therefore, we can just
23366569d68745c8213709740337d2be52b031384f58Douglas Gregor    // remove this nested class.
2337d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    DeallocateParsedClasses(Victim);
23386569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
23396569d68745c8213709740337d2be52b031384f58Douglas Gregor  }
23406569d68745c8213709740337d2be52b031384f58Douglas Gregor
23416569d68745c8213709740337d2be52b031384f58Douglas Gregor  // This nested class has some members that will need to be processed
23426569d68745c8213709740337d2be52b031384f58Douglas Gregor  // after the top-level class is completely defined. Therefore, add
23436569d68745c8213709740337d2be52b031384f58Douglas Gregor  // it to the list of nested classes within its parent.
234423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  assert(getCurScope()->isClassScope() && "Nested class outside of class scope?");
2345d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ClassStack.top()->LateParsedDeclarations.push_back(new LateParsedClass(this, Victim));
234623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor  Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope();
23476569d68745c8213709740337d2be52b031384f58Douglas Gregor}
2348bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2349bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// ParseCXX0XAttributes - Parse a C++0x attribute-specifier. Currently only
2350bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// parses standard attributes.
2351bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2352bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-specifier:
2353bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' '[' attribute-list ']' ']'
2354bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2355bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-list:
2356bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute[opt]
2357bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-list ',' attribute[opt]
2358bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2359bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute:
2360bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-token attribute-argument-clause[opt]
2361bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2362bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-token:
2363bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
2364bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-scoped-token
2365bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2366bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-scoped-token:
2367bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-namespace '::' identifier
2368bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2369bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-namespace:
2370bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
2371bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2372bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-argument-clause:
2373bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
2374bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2375bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] balanced-token-seq:
2376bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token
2377bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token-seq balanced-token
2378bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2379bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] balanced-token:
2380bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
2381bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' balanced-token-seq ']'
2382bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '{' balanced-token-seq '}'
2383bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         any token but '(', ')', '[', ']', '{', or '}'
23847f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCallvoid Parser::ParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
23857f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                  SourceLocation *endLoc) {
2386bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
2387bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      && "Not a C++0x attribute list");
2388bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2389bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  SourceLocation StartLoc = Tok.getLocation(), Loc;
2390bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2391bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
2392bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
2393193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
2394bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Tok.is(tok::comma)) {
2395bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Diag(Tok.getLocation(), diag::err_expected_ident);
2396bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    ConsumeToken();
2397bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
2398bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2399bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  while (Tok.is(tok::identifier) || Tok.is(tok::comma)) {
2400bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // attribute not present
2401bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::comma)) {
2402bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
2403bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      continue;
2404bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2405bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2406bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    IdentifierInfo *ScopeName = 0, *AttrName = Tok.getIdentifierInfo();
2407bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceLocation ScopeLoc, AttrLoc = ConsumeToken();
2408193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
2409bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // scoped attribute
2410bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::coloncolon)) {
2411bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
2412bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2413bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      if (!Tok.is(tok::identifier)) {
2414bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        Diag(Tok.getLocation(), diag::err_expected_ident);
2415bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        SkipUntil(tok::r_square, tok::comma, true, true);
2416bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        continue;
2417bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2418193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
2419bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ScopeName = AttrName;
2420bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ScopeLoc = AttrLoc;
2421bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2422bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttrName = Tok.getIdentifierInfo();
2423bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttrLoc = ConsumeToken();
2424bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2425bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2426bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    bool AttrParsed = false;
2427bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // No scoped names are supported; ideally we could put all non-standard
2428bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // attributes into namespaces.
2429bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (!ScopeName) {
2430bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      switch(AttributeList::getKind(AttrName))
2431bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      {
2432bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // No arguments
24337725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_carries_dependency:
243415e14a289583616e582a23b320933e846a742626Anders Carlsson      case AttributeList::AT_noreturn: {
2435bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        if (Tok.is(tok::l_paren)) {
2436bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          Diag(Tok.getLocation(), diag::err_cxx0x_attribute_forbids_arguments)
2437bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt            << AttrName->getName();
2438bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          break;
2439bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        }
2440bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
24410b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall        attrs.addNew(AttrName, AttrLoc, 0, AttrLoc, 0,
24420b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                     SourceLocation(), 0, 0, false, true);
2443bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        AttrParsed = true;
2444bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        break;
2445bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2446bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2447bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // One argument; must be a type-id or assignment-expression
2448bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      case AttributeList::AT_aligned: {
2449bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        if (Tok.isNot(tok::l_paren)) {
2450bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          Diag(Tok.getLocation(), diag::err_cxx0x_attribute_requires_arguments)
2451bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt            << AttrName->getName();
2452bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          break;
2453bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        }
2454bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        SourceLocation ParamLoc = ConsumeParen();
2455bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
245660d7b3a319d84d688752be3870615ac0f111fb16John McCall        ExprResult ArgExpr = ParseCXX0XAlignArgument(ParamLoc);
2457bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2458bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        MatchRHSPunctuation(tok::r_paren, ParamLoc);
2459bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2460bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        ExprVector ArgExprs(Actions);
2461bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        ArgExprs.push_back(ArgExpr.release());
24620b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall        attrs.addNew(AttrName, AttrLoc, 0, AttrLoc,
24630b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                     0, ParamLoc, ArgExprs.take(), 1,
24640b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall                     false, true);
2465bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2466bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        AttrParsed = true;
2467bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        break;
2468bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2469bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2470bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // Silence warnings
2471bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      default: break;
2472bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
2473bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2474bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2475bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // Skip the entire parameter clause, if any
2476bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (!AttrParsed && Tok.is(tok::l_paren)) {
2477bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeParen();
2478bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // SkipUntil maintains the balancedness of tokens.
2479bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      SkipUntil(tok::r_paren, false);
2480bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
2481bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
2482bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2483bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
2484bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
2485bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  Loc = Tok.getLocation();
2486bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
2487bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
2488bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
24897f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall  attrs.Range = SourceRange(StartLoc, Loc);
2490bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
2491bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2492bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// ParseCXX0XAlignArgument - Parse the argument to C++0x's [[align]]
2493bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute.
2494bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2495bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// FIXME: Simply returns an alignof() expression if the argument is a
2496bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// type. Ideally, the type should be propagated directly into Sema.
2497bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2498bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] 'align' '(' type-id ')'
2499bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] 'align' '(' assignment-expression ')'
250060d7b3a319d84d688752be3870615ac0f111fb16John McCallExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) {
2501bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (isTypeIdInParens()) {
2502f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall    EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
2503bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceLocation TypeLoc = Tok.getLocation();
2504b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall    ParsedType Ty = ParseTypeName().get();
2505bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceRange TypeRange(Start, Tok.getLocation());
2506f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne    return Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true,
2507f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne                                                Ty.getAsOpaquePtr(), TypeRange);
2508bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  } else
2509bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return ParseConstantExpression();
2510bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
2511334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet
2512334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ParseMicrosoftAttributes - Parse a Microsoft attribute [Attr]
2513334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///
2514334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute:
2515334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             '[' token-seq ']'
2516334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///
2517334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute-seq:
2518334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             ms-attribute[opt]
2519334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet///             ms-attribute ms-attribute-seq
25207f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCallvoid Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs,
25217f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall                                      SourceLocation *endLoc) {
2522334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
2523334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet
2524334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  while (Tok.is(tok::l_square)) {
2525334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    ConsumeBracket();
2526334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    SkipUntil(tok::r_square, true, true);
25277f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall    if (endLoc) *endLoc = Tok.getLocation();
2528334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet    ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
2529334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet  }
2530334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet}
2531