ParseDeclCXX.cpp revision 08d92ecf6e5b1fd23177a08c2312b58d63d863db
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"
17e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor#include "clang/Parse/DeclSpec.h"
188f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner#include "clang/Parse/Scope.h"
19314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor#include "clang/Parse/Template.h"
20d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner#include "RAIIObjectsForParser.h"
218f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattnerusing namespace clang;
228f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner
238f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// ParseNamespace - We know that the current token is a namespace keyword. This
248f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// may either be a top level namespace or a block-level namespace alias.
258f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
268f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       namespace-definition: [C++ 7.3: basic.namespace]
278f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         named-namespace-definition
288f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         unnamed-namespace-definition
298f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
308f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       unnamed-namespace-definition:
318f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         'namespace' attributes[opt] '{' namespace-body '}'
328f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
338f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       named-namespace-definition:
348f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         original-namespace-definition
358f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         extension-namespace-definition
368f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
378f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       original-namespace-definition:
388f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         'namespace' identifier attributes[opt] '{' namespace-body '}'
398f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
408f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       extension-namespace-definition:
418f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         'namespace' original-namespace-name '{' namespace-body '}'
421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
438f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///       namespace-alias-definition:  [C++ 7.3.2: namespace.alias]
448f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///         'namespace' identifier '=' qualified-namespace-specifier ';'
458f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner///
4697144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris LattnerParser::DeclPtrTy Parser::ParseNamespace(unsigned Context,
4797144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                         SourceLocation &DeclEnd) {
4804d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
498f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation NamespaceLoc = ConsumeToken();  // eat the 'namespace'.
501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5149f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
5249f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor    Actions.CodeCompleteNamespaceDecl(CurScope);
5349f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor    ConsumeToken();
5449f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
5549f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor
568f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  SourceLocation IdentLoc;
578f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  IdentifierInfo *Ident = 0;
586a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
596a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  Token attrTok;
601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6104d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner  if (Tok.is(tok::identifier)) {
628f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    Ident = Tok.getIdentifierInfo();
638f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    IdentLoc = ConsumeToken();  // eat the identifier.
648f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  }
651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
668f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner  // Read label attributes, if present.
67b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner  Action::AttrTy *AttrList = 0;
686a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::kw___attribute)) {
696a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor    attrTok = Tok;
706a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
718f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    // FIXME: save these somewhere.
72bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = ParseGNUAttributes();
736a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
756a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::equal)) {
766a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor    if (AttrList)
776a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor      Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
786a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
7997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
806a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  }
811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
825144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  if (Tok.isNot(tok::l_brace)) {
831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Diag(Tok, Ident ? diag::err_expected_lbrace :
845144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner         diag::err_expected_ident_lbrace);
855144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner    return DeclPtrTy();
865144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  }
871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
885144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  SourceLocation LBrace = ConsumeBrace();
892d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
905144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Enter a scope for the namespace.
915144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  ParseScope NamespaceScope(this, Scope::DeclScope);
922d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
935144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  DeclPtrTy NamespcDecl =
945144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner    Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace);
952d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
965144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions,
975144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner                                        PP.getSourceManager(),
985144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner                                        "parsing namespace");
991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
100bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
101bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    CXX0XAttributeList Attr;
102bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
103bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      Attr = ParseCXX0XAttributes();
104bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    ParseExternalDeclaration(Attr);
105bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1075144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Leave the namespace scope.
1085144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  NamespaceScope.Exit();
1098ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis
11097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBrace);
11197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  Actions.ActOnFinishNamespaceDef(NamespcDecl, RBraceLoc);
1122d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
11397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = RBraceLoc;
1145144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  return NamespcDecl;
1158f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner}
116c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
117f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
118f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// alias definition.
119f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson///
12003bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders CarlssonParser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                              SourceLocation AliasLoc,
12297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                              IdentifierInfo *Alias,
12397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                              SourceLocation &DeclEnd) {
124f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  assert(Tok.is(tok::equal) && "Not equal token");
1251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
126f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  ConsumeToken(); // eat the '='.
1271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12849f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
12949f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor    Actions.CodeCompleteNamespaceAliasDecl(CurScope);
13049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor    ConsumeToken();
13149f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
13249f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor
133f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  CXXScopeSpec SS;
134f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse (optional) nested-name-specifier.
135be1ea44be73facdb60edae34c2fb1a38dafcb28cChris Lattner  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
136f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
137f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
138f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    Diag(Tok, diag::err_expected_namespace_name);
139f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    // Skip to end of the definition and eat the ';'.
140f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    SkipUntil(tok::semi);
141b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
142f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  }
143f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
144f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse identifier.
14503bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  IdentifierInfo *Ident = Tok.getIdentifierInfo();
14603bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  SourceLocation IdentLoc = ConsumeToken();
1471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
148f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Eat the ';'.
14997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
1506869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name,
1516869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner                   "", tok::semi);
1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return Actions.ActOnNamespaceAliasDef(CurScope, NamespaceLoc, AliasLoc, Alias,
15403bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson                                        SS, IdentLoc, Ident);
155f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson}
156f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
157c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal
158c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen.
159c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
160c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///       linkage-specification: [C++ 7.5p2: dcl.link]
161c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal '{' declaration-seq[opt] '}'
162c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal declaration
163c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
1643acd9aaa4ddd14afecb4f1c02ca6f585a6d51849Fariborz JahanianParser::DeclPtrTy Parser::ParseLinkage(ParsingDeclSpec &DS,
1653acd9aaa4ddd14afecb4f1c02ca6f585a6d51849Fariborz Jahanian                                       unsigned Context) {
166c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor  assert(Tok.is(tok::string_literal) && "Not a string literal!");
167c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  llvm::SmallVector<char, 8> LangBuffer;
168c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  // LangBuffer is guaranteed to be big enough.
169c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  LangBuffer.resize(Tok.getLength());
170c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  const char *LangBufPtr = &LangBuffer[0];
171c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  unsigned StrSize = PP.getSpelling(Tok, LangBufPtr);
172c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
173c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  SourceLocation Loc = ConsumeStringToken();
174c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
175074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  ParseScope LinkageScope(this, Scope::DeclScope);
1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  DeclPtrTy LinkageSpec
1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    = Actions.ActOnStartLinkageSpecification(CurScope,
178074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                             /*FIXME: */SourceLocation(),
179074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                             Loc, LangBufPtr, StrSize,
1801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                       Tok.is(tok::l_brace)? Tok.getLocation()
181074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                           : SourceLocation());
182074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
183bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  CXX0XAttributeList Attr;
184bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
185bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Attr = ParseCXX0XAttributes();
186bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
187bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
188074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (Tok.isNot(tok::l_brace)) {
1893acd9aaa4ddd14afecb4f1c02ca6f585a6d51849Fariborz Jahanian    ParseDeclarationOrFunctionDefinition(DS, Attr.AttrList);
1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec,
191074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                   SourceLocation());
1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
193f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor
194bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Attr.HasAttr)
195bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
196bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      << Attr.Range;
197bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
198f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  SourceLocation LBrace = ConsumeBrace();
199f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
200bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    CXX0XAttributeList Attr;
201bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
202bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      Attr = ParseCXX0XAttributes();
203bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    ParseExternalDeclaration(Attr);
204f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  }
205c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
206f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
207074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, RBrace);
208c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner}
209e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
210f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
211f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'.
21297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris LattnerParser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
213bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                                     SourceLocation &DeclEnd,
214bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                                     CXX0XAttributeList Attr) {
215f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_using) && "Not using token");
216f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
217f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'using'.
218f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation UsingLoc = ConsumeToken();
219f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
22049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
22149f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor    Actions.CodeCompleteUsing(CurScope);
22249f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor    ConsumeToken();
22349f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
22449f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor
2252f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner  if (Tok.is(tok::kw_namespace))
226f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // Next token after 'using' is 'namespace' so it must be using-directive
227bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return ParseUsingDirective(Context, UsingLoc, DeclEnd, Attr.AttrList);
228bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
229bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Attr.HasAttr)
230bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
231bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      << Attr.Range;
2322f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner
2332f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner  // Otherwise, it must be using-declaration.
234bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // Ignore illegal attributes (the caller should already have issued an error.
23597144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  return ParseUsingDeclaration(Context, UsingLoc, DeclEnd);
236f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
237f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
238f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes
239f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed.
240f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
241f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       using-directive: [C++ 7.3.p4: namespace.udir]
242f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
243f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name ;
244f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive:
245f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
246f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name attributes[opt] ;
247f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
248b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris LattnerParser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
24997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                              SourceLocation UsingLoc,
250bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                              SourceLocation &DeclEnd,
251bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                              AttributeList *Attr) {
252f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
253f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
254f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'namespace'.
255f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation NamespcLoc = ConsumeToken();
256f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
25749f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
25849f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor    Actions.CodeCompleteUsingDirective(CurScope);
25949f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor    ConsumeToken();
26049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
26149f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor
262f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  CXXScopeSpec SS;
263f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse (optional) nested-name-specifier.
264be1ea44be73facdb60edae34c2fb1a38dafcb28cChris Lattner  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
265f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
266f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  IdentifierInfo *NamespcName = 0;
267f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation IdentLoc = SourceLocation();
268f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
269f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse namespace-name.
270823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
271f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    Diag(Tok, diag::err_expected_namespace_name);
272f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // If there was invalid namespace name, skip to end of decl, and eat ';'.
273f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    SkipUntil(tok::semi);
274f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
275b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
276f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  }
2771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
278823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse identifier.
279823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  NamespcName = Tok.getIdentifierInfo();
280823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  IdentLoc = ConsumeToken();
2811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
282823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse (optional) attributes (most likely GNU strong-using extension).
283bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  bool GNUAttr = false;
284bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Tok.is(tok::kw___attribute)) {
285bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    GNUAttr = true;
286bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Attr = addAttributeLists(Attr, ParseGNUAttributes());
287bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
2881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
289823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Eat ';'.
29097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
2916869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi,
292bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                   GNUAttr ? diag::err_expected_semi_after_attribute_list :
2936869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner                   diag::err_expected_semi_after_namespace_name, "", tok::semi);
294f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
295f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  return Actions.ActOnUsingDirective(CurScope, UsingLoc, NamespcLoc, SS,
296bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                      IdentLoc, NamespcName, Attr);
297f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
298f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
299f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that
300f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' was already seen.
301f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
302f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///     using-declaration: [C++ 7.3.p3: namespace.udecl]
303f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       'using' 'typename'[opt] ::[opt] nested-name-specifier
3049cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///               unqualified-id
3059cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///       'using' :: unqualified-id
306f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
307b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris LattnerParser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
30897144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                                SourceLocation UsingLoc,
309595adc1795cc2c079ef5876100e01acd10a0504aAnders Carlsson                                                SourceLocation &DeclEnd,
310595adc1795cc2c079ef5876100e01acd10a0504aAnders Carlsson                                                AccessSpecifier AS) {
3119cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  CXXScopeSpec SS;
3127ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall  SourceLocation TypenameLoc;
3139cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  bool IsTypeName;
3149cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3159cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Ignore optional 'typename'.
31612c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // FIXME: This is wrong; we should parse this as a typename-specifier.
3179cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_typename)) {
3187ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall    TypenameLoc = Tok.getLocation();
3199cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    ConsumeToken();
3209cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = true;
3219cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
3229cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  else
3239cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = false;
3249cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3259cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Parse nested-name-specifier.
326be1ea44be73facdb60edae34c2fb1a38dafcb28cChris Lattner  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
3279cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3289cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  AttributeList *AttrList = 0;
3299cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3309cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Check nested-name specifier.
3319cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (SS.isInvalid()) {
3329cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
3339cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return DeclPtrTy();
3349cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
3351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33612c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // Parse the unqualified-id. We allow parsing of both constructor and
33712c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // destructor names and allow the action module to diagnose any semantic
33812c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // errors.
33912c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  UnqualifiedId Name;
34012c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  if (ParseUnqualifiedId(SS,
34112c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*EnteringContext=*/false,
34212c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*AllowDestructorName=*/true,
34312c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*AllowConstructorName=*/true,
34412c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*ObjectType=*/0,
34512c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         Name)) {
3469cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
3479cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return DeclPtrTy();
3489cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
34912c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor
3509cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Parse (optional) attributes (most likely GNU strong-using extension).
3519cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw___attribute))
352bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = ParseGNUAttributes();
3531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3549cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Eat ';'.
3559cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  DeclEnd = Tok.getLocation();
3569cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
35712c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                   AttrList ? "attributes list" : "using declaration",
35812c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                   tok::semi);
3599cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
36012c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  return Actions.ActOnUsingDeclaration(CurScope, AS, UsingLoc, SS, Name,
3617ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall                                       AttrList, IsTypeName, TypenameLoc);
362f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
363f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
364511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
365511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
366511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///      static_assert-declaration:
367511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///        static_assert ( constant-expression  ,  string-literal  ) ;
368511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
36997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris LattnerParser::DeclPtrTy Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
370511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
371511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation StaticAssertLoc = ConsumeToken();
3721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
373511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (Tok.isNot(tok::l_paren)) {
374511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_lparen);
375b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
376511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
378511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation LParenLoc = ConsumeParen();
379e0762c92110dfdcdd207db461a4ea17afd168f1eDouglas Gregor
380511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  OwningExprResult AssertExpr(ParseConstantExpression());
381511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (AssertExpr.isInvalid()) {
382511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    SkipUntil(tok::semi);
383b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
384511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
3851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
386ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
387b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
388ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson
389511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (Tok.isNot(tok::string_literal)) {
390511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_string_literal);
391511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    SkipUntil(tok::semi);
392b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
393511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
3941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
395511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  OwningExprResult AssertMessage(ParseStringLiteralExpression());
3961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (AssertMessage.isInvalid())
397b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
398511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
39994b15fbc3a10cdfb1639528a8a773b66a1e7cd9eAnders Carlsson  MatchRHSPunctuation(tok::r_paren, LParenLoc);
4001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
402511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert);
403511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
4041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, move(AssertExpr),
40594b15fbc3a10cdfb1639528a8a773b66a1e7cd9eAnders Carlsson                                              move(AssertMessage));
406511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson}
407511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
4086fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// ParseDecltypeSpecifier - Parse a C++0x decltype specifier.
4096fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
4106fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 'decltype' ( expression )
4116fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
4126fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlssonvoid Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
4136fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  assert(Tok.is(tok::kw_decltype) && "Not a decltype specifier");
4146fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
4156fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation StartLoc = ConsumeToken();
4166fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation LParenLoc = Tok.getLocation();
4171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
4196fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson                       "decltype")) {
4206fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    SkipUntil(tok::r_paren);
4216fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
4226fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  }
4231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4246fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Parse the expression
4251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4266fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // C++0x [dcl.type.simple]p4:
4276fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  //   The operand of the decltype specifier is an unevaluated operand.
4286fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  EnterExpressionEvaluationContext Unevaluated(Actions,
4296fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson                                               Action::Unevaluated);
4306fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  OwningExprResult Result = ParseExpression();
4316fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (Result.isInvalid()) {
4326fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    SkipUntil(tok::r_paren);
4336fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
4346fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  }
4351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4366fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Match the ')'
4376fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation RParenLoc;
4386fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (Tok.is(tok::r_paren))
4396fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    RParenLoc = ConsumeParen();
4406fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  else
4416fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    MatchRHSPunctuation(tok::r_paren, LParenLoc);
4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4436fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (RParenLoc.isInvalid())
4446fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
4456fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
4466fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  const char *PrevSpec = 0;
447fec54013fcd0eb72642741584ca04c1bc292bef8John McCall  unsigned DiagID;
4486fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Check for duplicate type specifiers (e.g. "int decltype(a)").
4491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec,
450fec54013fcd0eb72642741584ca04c1bc292bef8John McCall                         DiagID, Result.release()))
451fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
4526fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson}
4536fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
45442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// ParseClassName - Parse a C++ class-name, which names a class. Note
45542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// that we only check that the result names a type; semantic analysis
45642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// will need to verify that the type names a class. The result is
4577f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor/// either a type or NULL, depending on whether a type name was
45842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// found.
45942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///
46042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///       class-name: [C++ 9.1]
46142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///         identifier
4627f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor///         simple-template-id
4631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
46431a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas GregorParser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
465d33c868d386ef47c2942e2dbff0d9955a8591fa9Fariborz Jahanian                                          const CXXScopeSpec *SS,
466d33c868d386ef47c2942e2dbff0d9955a8591fa9Fariborz Jahanian                                          bool DestrExpected) {
4677f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  // Check whether we have a template-id that names a type.
4687f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  if (Tok.is(tok::annot_template_id)) {
4691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    TemplateIdAnnotation *TemplateId
4707f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
471c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor    if (TemplateId->Kind == TNK_Type_template) {
47231a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      AnnotateTemplateIdTokenAsType(SS);
4737f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
4747f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
4757f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      TypeTy *Type = Tok.getAnnotationValue();
4767f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      EndLocation = Tok.getAnnotationEndLoc();
4777f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      ConsumeToken();
47831a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor
47931a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      if (Type)
48031a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor        return Type;
48131a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      return true;
4827f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    }
4837f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
4847f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    // Fall through to produce an error below.
4857f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  }
4867f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
48742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  if (Tok.isNot(tok::identifier)) {
4881ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_class_name);
48931a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
49042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
49142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
49242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // We have an identifier; check whether it is actually a type.
4931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(),
49442c39f39184c5ce9d7f489e5dcb7eec770728a9aDouglas Gregor                                     Tok.getLocation(), CurScope, SS,
49542c39f39184c5ce9d7f489e5dcb7eec770728a9aDouglas Gregor                                     true);
49642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  if (!Type) {
4971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Diag(Tok, DestrExpected ? diag::err_destructor_class_name
498d33c868d386ef47c2942e2dbff0d9955a8591fa9Fariborz Jahanian                            : diag::err_expected_class_name);
49931a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
50042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
50142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
50242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Consume the identifier.
5037f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  EndLocation = ConsumeToken();
50442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  return Type;
50542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor}
50642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
507e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
508e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
509e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that
510e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// cannot start a definition.
511e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
512e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-specifier: [C++ class]
513e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}'
514e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}' attributes[opt]
515e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-head:
516e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key identifier[opt] base-clause[opt]
517e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier identifier base-clause[opt]
518e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier[opt] simple-template-id
519e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          base-clause[opt]
520e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   class-key attributes[opt] identifier[opt] base-clause[opt]
5211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier
522e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          identifier base-clause[opt]
5231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier[opt]
524e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          simple-template-id base-clause[opt]
525e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-key:
526e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'class'
527e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
528e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
529e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
530e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       elaborated-type-specifier: [C++ dcl.type.elab]
5311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] identifier
5321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
5331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///                          simple-template-id
534e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
535e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  Note that the C++ class-specifier and elaborated-type-specifier,
536e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  together, subsume the C99 struct-or-union-specifier:
537e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
538e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union-specifier: [C99 6.7.2.1]
539e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier[opt] '{' struct-contents '}'
540e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier
541e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier[opt] '{' struct-contents
542e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                                                         '}' attributes[opt]
543e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier
544e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union:
545e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
546e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
5474c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattnervoid Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
5484c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner                                 SourceLocation StartLoc, DeclSpec &DS,
5494d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                 const ParsedTemplateInfo &TemplateInfo,
55006c0fecd197fef21e265a41bca8dc5022de1f864Douglas Gregor                                 AccessSpecifier AS) {
5514c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  DeclSpec::TST TagType;
5524c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  if (TagTokKind == tok::kw_struct)
5534c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_struct;
5544c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  else if (TagTokKind == tok::kw_class)
5554c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_class;
5564c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  else {
5574c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    assert(TagTokKind == tok::kw_union && "Not a class specifier");
5584c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_union;
5594c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  }
560e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
561374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  if (Tok.is(tok::code_completion)) {
562374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor    // Code completion for a struct, class, or union name.
563374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor    Actions.CodeCompleteTag(CurScope, TagType);
564374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor    ConsumeToken();
565374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  }
566374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor
567bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  AttributeList *AttrList = 0;
568e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If attributes exist after tag, parse them.
569e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw___attribute))
570bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = ParseGNUAttributes();
571e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
572f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff  // If declspecs exist after tag, parse them.
573290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman  if (Tok.is(tok::kw___declspec))
574bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = ParseMicrosoftDeclSpec(AttrList);
575bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
576bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // If C++0x attributes exist here, parse them.
577bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Are we consistent with the ordering of parsing of different
578bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // styles of attributes?
579bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (isCXX0XAttributeSpecifier())
580bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = addAttributeLists(AttrList, ParseCXX0XAttributes().AttrList);
5811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
582b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_pod)) {
583b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // GNU libstdc++ 4.2 uses __is_pod as the name of a struct template, but
584b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // __is_pod is a keyword in GCC >= 4.3. Therefore, when we see the
5851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // token sequence "struct __is_pod", make __is_pod into a normal
586b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // identifier rather than a keyword, to allow libstdc++ 4.2 to work
587b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // properly.
588b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.getIdentifierInfo()->setTokenID(tok::identifier);
589b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.setKind(tok::identifier);
590b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  }
591b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor
592b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_empty)) {
593b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // GNU libstdc++ 4.2 uses __is_empty as the name of a struct template, but
594b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // __is_empty is a keyword in GCC >= 4.3. Therefore, when we see the
5951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // token sequence "struct __is_empty", make __is_empty into a normal
596b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // identifier rather than a keyword, to allow libstdc++ 4.2 to work
597b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // properly.
598b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.getIdentifierInfo()->setTokenID(tok::identifier);
599b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.setKind(tok::identifier);
600b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  }
6011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
602eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse the (optional) nested-name-specifier.
603eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  CXXScopeSpec SS;
60408d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  if (getLang().CPlusPlus) {
60508d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    // "FOO : BAR" is not a potential typo for "FOO::BAR".
60608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    ColonProtectionRAIIObject X(*this);
60708d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner
60808d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true))
60908d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner      if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
61008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner        Diag(Tok, diag::err_expected_ident);
61108d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  }
612cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
6132cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor  TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
6142cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor
615cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  // Parse the (optional) class name or simple-template-id.
616e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  IdentifierInfo *Name = 0;
617e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation NameLoc;
61839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  TemplateIdAnnotation *TemplateId = 0;
619e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::identifier)) {
620e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    Name = Tok.getIdentifierInfo();
621e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    NameLoc = ConsumeToken();
6222cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor
6232cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor    if (Tok.is(tok::less)) {
6242cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // The name was supposed to refer to a template, but didn't.
6252cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // Eat the template argument list and try to continue parsing this as
6262cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // a class (or template thereof).
6272cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      TemplateArgList TemplateArgs;
6282cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      SourceLocation LAngleLoc, RAngleLoc;
6292cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, &SS,
6302cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor                                           true, LAngleLoc,
631314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor                                           TemplateArgs, RAngleLoc)) {
6322cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // We couldn't parse the template argument list at all, so don't
6332cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // try to give any location information for the list.
6342cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        LAngleLoc = RAngleLoc = SourceLocation();
6352cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
6362cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor
6372cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      Diag(NameLoc, diag::err_explicit_spec_non_template)
638c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
6392cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << (TagType == DeclSpec::TST_class? 0
6402cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor            : TagType == DeclSpec::TST_struct? 1
6412cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor            : 2)
6422cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << Name
6432cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << SourceRange(LAngleLoc, RAngleLoc);
6442cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor
645c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      // Strip off the last template parameter list if it was empty, since
646c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      // we've removed its template argument list.
647c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
648c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        if (TemplateParams && TemplateParams->size() > 1) {
649c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams->pop_back();
650c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        } else {
651c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams = 0;
652c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
653c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor            = ParsedTemplateInfo::NonTemplate;
654c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        }
655c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      } else if (TemplateInfo.Kind
656c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor                                == ParsedTemplateInfo::ExplicitInstantiation) {
657c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        // Pretend this is just a forward declaration.
6582cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        TemplateParams = 0;
6592cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
6602cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor          = ParsedTemplateInfo::NonTemplate;
661c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc
662c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
663c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc
664c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
6652cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
666c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor
6672cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor
6682cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor    }
66939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  } else if (Tok.is(tok::annot_template_id)) {
67039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
67139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    NameLoc = ConsumeToken();
672cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
673c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor    if (TemplateId->Kind != TNK_Type_template) {
67439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // The template-name in the simple-template-id refers to
67539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // something other than a class template. Give an appropriate
67639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // error message and skip to the ';'.
67739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SourceRange Range(NameLoc);
67839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      if (SS.isNotEmpty())
67939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        Range.setBegin(SS.getBeginLoc());
68039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
68139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
68239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        << Name << static_cast<int>(TemplateId->Kind) << Range;
6831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      DS.SetTypeSpecError();
68539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SkipUntil(tok::semi, false, true);
68639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      TemplateId->Destroy();
68739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      return;
688cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    }
689e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
690e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
69167d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  // There are four options here.  If we have 'struct foo;', then this
69267d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  // is either a forward declaration or a friend declaration, which
69367d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  // have to be treated differently.  If we have 'struct foo {...' or
69439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  // 'struct foo :...' then this is a definition. Otherwise we have
695e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // something like 'struct foo xyz', a reference.
6960f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall  Action::TagUseKind TUK;
697d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor  if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))) {
698d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    if (DS.isFriendSpecified()) {
699d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // C++ [class.friend]p2:
700d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      //   A class shall not be defined in a friend declaration.
701d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      Diag(Tok.getLocation(), diag::err_friend_decl_defines_class)
702d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor        << SourceRange(DS.getFriendSpecLoc());
703d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor
704d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Skip everything up to the semicolon, so that this looks like a proper
705d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // friend class (or template thereof) declaration.
706d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      SkipUntil(tok::semi, true, true);
707d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      TUK = Action::TUK_Friend;
708d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    } else {
709d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Okay, this is a class definition.
710d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      TUK = Action::TUK_Definition;
711d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    }
712d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor  } else if (Tok.is(tok::semi))
71367d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    TUK = DS.isFriendSpecified() ? Action::TUK_Friend : Action::TUK_Declaration;
714e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  else
7150f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall    TUK = Action::TUK_Reference;
716e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
7170f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall  if (!Name && !TemplateId && TUK != Action::TUK_Definition) {
718e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // We have a declaration or reference to an anonymous class.
7191ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(StartLoc, diag::err_anon_type_definition)
7201ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner      << DeclSpec::getSpecifierName(TagType);
721e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
722e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SkipUntil(tok::comma, true);
72339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
72439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    if (TemplateId)
72539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      TemplateId->Destroy();
726e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    return;
727e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
728e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
729ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  // Create the tag portion of the class or class template.
730c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  Action::DeclResult TagOrTempResult = true; // invalid
731c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  Action::TypeResult TypeResult = true; // invalid
7324d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
7330f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall  // FIXME: When TUK == TUK_Reference and we have a template-id, we need
7344d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor  // to turn that template-id into a type.
7354d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
736402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor  bool Owned = false;
737f1bbbb49f06a7462476cd88166fccda5feb15cabJohn McCall  if (TemplateId) {
7384d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // Explicit specialization, class template partial specialization,
7394d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // or explicit instantiation.
7401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ASTTemplateArgsPtr TemplateArgsPtr(Actions,
74139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->getTemplateArgs(),
74239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->NumArgs);
7434d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
7440f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall        TUK == Action::TUK_Declaration) {
7454d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit instantiation of a class template.
7464d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
7471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        = Actions.ActOnExplicitInstantiation(CurScope,
74845f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                             TemplateInfo.ExternLoc,
7491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateInfo.TemplateLoc,
7504d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TagType,
7511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             StartLoc,
7524d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             SS,
7531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     TemplateTy::make(TemplateId->Template),
7541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->TemplateNameLoc,
7551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->LAngleLoc,
7564d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateArgsPtr,
7571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->RAngleLoc,
758bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                             AttrList);
759fc9cd61f2372cd8f43f0d92be14fa75778de6be6Douglas Gregor    } else if (TUK == Action::TUK_Reference) {
760c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall      TypeResult
7616b2becfc434b0bdced8560802c4d0e03148c61b8John McCall        = Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
7626b2becfc434b0bdced8560802c4d0e03148c61b8John McCall                                      TemplateId->TemplateNameLoc,
7636b2becfc434b0bdced8560802c4d0e03148c61b8John McCall                                      TemplateId->LAngleLoc,
7646b2becfc434b0bdced8560802c4d0e03148c61b8John McCall                                      TemplateArgsPtr,
7656b2becfc434b0bdced8560802c4d0e03148c61b8John McCall                                      TemplateId->RAngleLoc);
7666b2becfc434b0bdced8560802c4d0e03148c61b8John McCall
767c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall      TypeResult = Actions.ActOnTagTemplateIdType(TypeResult, TUK,
768c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall                                                  TagType, StartLoc);
7694d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    } else {
7704d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit specialization or a class template
7714d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // partial specialization.
7724d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TemplateParameterLists FakedParamLists;
7734d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
7744d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
7754d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // This looks like an explicit instantiation, because we have
7764d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // something like
7774d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
7784d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //   template class Foo<X>
7794d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
7803f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor        // but it actually has a definition. Most likely, this was
7814d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // meant to be an explicit specialization, but the user forgot
7824d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // the '<>' after 'template'.
7830f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall        assert(TUK == Action::TUK_Definition && "Expected a definition here");
7844d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
7851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        SourceLocation LAngleLoc
7864d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
7871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        Diag(TemplateId->TemplateNameLoc,
7884d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor             diag::err_explicit_instantiation_with_definition)
7894d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          << SourceRange(TemplateInfo.TemplateLoc)
7904d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          << CodeModificationHint::CreateInsertion(LAngleLoc, "<>");
7914d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
7924d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // Create a fake template parameter list that contains only
7934d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // "template<>", so that we treat this construct as a class
7944d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // template specialization.
7954d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        FakedParamLists.push_back(
7961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          Actions.ActOnTemplateParameterList(0, SourceLocation(),
7974d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateInfo.TemplateLoc,
7981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             LAngleLoc,
7991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             0, 0,
8004d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             LAngleLoc));
8014d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        TemplateParams = &FakedParamLists;
8024d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      }
8034d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
8044d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // Build the class template specialization.
8054d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
8060f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall        = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TUK,
80739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       StartLoc, SS,
8081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateTy::make(TemplateId->Template),
8091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->TemplateNameLoc,
8101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->LAngleLoc,
81139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       TemplateArgsPtr,
8121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->RAngleLoc,
813bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                       AttrList,
8141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       Action::MultiTemplateParamsArg(Actions,
815cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                    TemplateParams? &(*TemplateParams)[0] : 0,
816cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                 TemplateParams? TemplateParams->size() : 0));
8174d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    }
81839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    TemplateId->Destroy();
8193f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
8200f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall             TUK == Action::TUK_Declaration) {
8213f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Explicit instantiation of a member of a class template
8223f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // specialization, e.g.,
8233f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
8243f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //   template struct Outer<int>::Inner;
8253f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
8263f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    TagOrTempResult
8271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      = Actions.ActOnExplicitInstantiation(CurScope,
82845f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                           TemplateInfo.ExternLoc,
8291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TemplateInfo.TemplateLoc,
8301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TagType, StartLoc, SS, Name,
831bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                           NameLoc, AttrList);
8323f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else {
8333f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
8340f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall        TUK == Action::TUK_Definition) {
8353f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor      // FIXME: Diagnose this particular error.
8363f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    }
8373f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor
838c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    bool IsDependent = false;
839c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
8403f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Declaration or definition of a class type
8411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    TagOrTempResult = Actions.ActOnTag(CurScope, TagType, TUK, StartLoc, SS,
842bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                       Name, NameLoc, AttrList, AS,
8431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                  Action::MultiTemplateParamsArg(Actions,
8447cdbc5832084f45721693dfb1d93284c3e08efeeDouglas Gregor                                    TemplateParams? &(*TemplateParams)[0] : 0,
8457cdbc5832084f45721693dfb1d93284c3e08efeeDouglas Gregor                                    TemplateParams? TemplateParams->size() : 0),
846c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall                                       Owned, IsDependent);
847c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
848c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // If ActOnTag said the type was dependent, try again with the
849c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // less common call.
850c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    if (IsDependent)
851c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall      TypeResult = Actions.ActOnDependentTag(CurScope, TagType, TUK,
852c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall                                             SS, Name, StartLoc, NameLoc);
8533f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  }
854e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
855e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the optional base clause (C++ only).
85622bd905673a73ccb9b5e45a7038ec060c9650ffeChris Lattner  if (getLang().CPlusPlus && Tok.is(tok::colon))
857212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor    ParseBaseClause(TagOrTempResult.get());
858e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
859e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If there is a body, parse it and inform the actions module.
860e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::l_brace))
86107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    if (getLang().CPlusPlus)
862212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
86307952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    else
864212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
8650f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall  else if (TUK == Action::TUK_Definition) {
866e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // FIXME: Complain that we have a base-specifier list but no
867e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // definition.
8681ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lbrace);
869e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
870e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
871c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  void *Result;
872c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  if (!TypeResult.isInvalid()) {
873c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    TagType = DeclSpec::TST_typename;
874c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    Result = TypeResult.get();
875c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    Owned = false;
876c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else if (!TagOrTempResult.isInvalid()) {
877c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    Result = TagOrTempResult.get().getAs<void>();
878c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else {
879ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    DS.SetTypeSpecError();
88066e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson    return;
88166e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson  }
8821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
883fec54013fcd0eb72642741584ca04c1bc292bef8John McCall  const char *PrevSpec = 0;
884fec54013fcd0eb72642741584ca04c1bc292bef8John McCall  unsigned DiagID;
885c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
886fec54013fcd0eb72642741584ca04c1bc292bef8John McCall  if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, DiagID,
887c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall                         Result, Owned))
888fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
889e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
890e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
8911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
892e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
893e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-clause : [C++ class.derived]
894e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ':' base-specifier-list
895e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier-list:
896e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier '...'[opt]
897e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier-list ',' base-specifier '...'[opt]
898b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattnervoid Parser::ParseBaseClause(DeclPtrTy ClassDecl) {
899e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  assert(Tok.is(tok::colon) && "Not a base clause");
900e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  ConsumeToken();
901e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
902f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Build up an array of parsed base specifiers.
903f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  llvm::SmallVector<BaseTy *, 8> BaseInfo;
904f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
905e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  while (true) {
906e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Parse a base-specifier.
907f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    BaseResult Result = ParseBaseSpecifier(ClassDecl);
9085ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor    if (Result.isInvalid()) {
909e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Skip the rest of this base specifier, up until the comma or
910e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // opening brace.
911f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      SkipUntil(tok::comma, tok::l_brace, true, true);
912f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    } else {
913f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      // Add this to our array of base specifiers.
9145ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor      BaseInfo.push_back(Result.get());
915e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
916e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
917e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // If the next token is a comma, consume it and keep reading
918e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // base-specifiers.
919e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (Tok.isNot(tok::comma)) break;
9201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
921e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Consume the comma.
922e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
923e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
924f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
925f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Attach the base specifiers
926beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad  Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size());
927e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
928e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
929e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
930e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example:
931e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///    class foo : public bar, virtual private baz {
932e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers.
933e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
934e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier: [C++ class.derived]
935e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ::[opt] nested-name-specifier[opt] class-name
936e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt]
937e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                        class-name
938e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
939e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                        class-name
940b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris LattnerParser::BaseResult Parser::ParseBaseSpecifier(DeclPtrTy ClassDecl) {
941e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  bool IsVirtual = false;
942e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation StartLoc = Tok.getLocation();
943e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
944e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword.
945e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
946e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
947e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
948e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
949e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
950e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse an (optional) access specifier.
951e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  AccessSpecifier Access = getAccessSpecifierIfPresent();
952e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Access)
953e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
9541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
955e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword (again!), in case it came after the
956e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // access specifier.
957e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
958e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SourceLocation VirtualLoc = ConsumeToken();
959e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (IsVirtual) {
960e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Complain about duplicate 'virtual'
9611ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner      Diag(VirtualLoc, diag::err_dup_virtual)
96229d9c1adfadf65e2d847d44bec37746844b9e0e3Chris Lattner        << CodeModificationHint::CreateRemoval(VirtualLoc);
963e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
964e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
965e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
966e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
967e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
968eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse optional '::' and optional nested-name-specifier.
969eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  CXXScopeSpec SS;
9702dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true);
971e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
972e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // The location of the base class itself.
973e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation BaseLoc = Tok.getLocation();
97442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
97542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Parse the class-name.
9767f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceLocation EndLocation;
97731a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor  TypeResult BaseType = ParseClassName(EndLocation, &SS);
97831a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor  if (BaseType.isInvalid())
97942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor    return true;
9801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Find the complete source range for the base-specifier.
9827f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceRange Range(StartLoc, EndLocation);
9831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
984e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Notify semantic analysis that we have parsed a complete
985e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // base-specifier.
986a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl  return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
98731a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor                                    BaseType.get(), BaseLoc);
988e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
989e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
990e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is
991e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier.
992e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
993e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       access-specifier: [C++ class.derived]
994e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'private'
995e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'protected'
996e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'public'
9971eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAccessSpecifier Parser::getAccessSpecifierIfPresent() const {
998e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  switch (Tok.getKind()) {
999e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  default: return AS_none;
1000e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_private: return AS_private;
1001e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_protected: return AS_protected;
1002e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_public: return AS_public;
1003e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1004e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
10054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1006d33133cdc1af466f9c276249b2621be03867888bEli Friedmanvoid Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
1007d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                             DeclPtrTy ThisDecl) {
1008d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // We just declared a member function. If this member function
1009d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // has any default arguments, we'll need to parse them later.
1010d33133cdc1af466f9c276249b2621be03867888bEli Friedman  LateParsedMethodDeclaration *LateMethod = 0;
10111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  DeclaratorChunk::FunctionTypeInfo &FTI
1012d33133cdc1af466f9c276249b2621be03867888bEli Friedman    = DeclaratorInfo.getTypeObject(0).Fun;
1013d33133cdc1af466f9c276249b2621be03867888bEli Friedman  for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
1014d33133cdc1af466f9c276249b2621be03867888bEli Friedman    if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
1015d33133cdc1af466f9c276249b2621be03867888bEli Friedman      if (!LateMethod) {
1016d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Push this method onto the stack of late-parsed method
1017d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // declarations.
1018d33133cdc1af466f9c276249b2621be03867888bEli Friedman        getCurrentClass().MethodDecls.push_back(
1019d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                LateParsedMethodDeclaration(ThisDecl));
1020d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateMethod = &getCurrentClass().MethodDecls.back();
1021d83d04041f64a2c89123d227fa8003b482391279Douglas Gregor        LateMethod->TemplateScope = CurScope->isTemplateParamScope();
1022d33133cdc1af466f9c276249b2621be03867888bEli Friedman
1023d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Add all of the parameters prior to this one (they don't
1024d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // have default arguments).
1025d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateMethod->DefaultArgs.reserve(FTI.NumArgs);
1026d33133cdc1af466f9c276249b2621be03867888bEli Friedman        for (unsigned I = 0; I < ParamIdx; ++I)
1027d33133cdc1af466f9c276249b2621be03867888bEli Friedman          LateMethod->DefaultArgs.push_back(
1028d33133cdc1af466f9c276249b2621be03867888bEli Friedman                    LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param));
1029d33133cdc1af466f9c276249b2621be03867888bEli Friedman      }
1030d33133cdc1af466f9c276249b2621be03867888bEli Friedman
1031d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // Add this parameter to the list of parameters (it or may
1032d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // not have a default argument).
1033d33133cdc1af466f9c276249b2621be03867888bEli Friedman      LateMethod->DefaultArgs.push_back(
1034d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
1035d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                  FTI.ArgInfo[ParamIdx].DefaultArgTokens));
1036d33133cdc1af466f9c276249b2621be03867888bEli Friedman    }
1037d33133cdc1af466f9c276249b2621be03867888bEli Friedman  }
1038d33133cdc1af466f9c276249b2621be03867888bEli Friedman}
1039d33133cdc1af466f9c276249b2621be03867888bEli Friedman
10404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
10414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
10424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declaration:
10434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         decl-specifier-seq[opt] member-declarator-list[opt] ';'
10444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         function-definition ';'[opt]
10454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
10464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         using-declaration                                            [TODO]
1047511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration
10485aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson///         template-declaration
1049bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU]   '__extension__' member-declaration
10504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
10514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator-list:
10524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator
10534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator-list ',' member-declarator
10544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
10554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator:
10564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         declarator pure-specifier[opt]
10574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         declarator constant-initializer[opt]
10584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         identifier[opt] ':' constant-expression
10594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
1060e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl///       pure-specifier:
10614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '= 0'
10624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
10634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       constant-initializer:
10644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '=' constant-expression
10654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
106637b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregorvoid Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
106737b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor                                       const ParsedTemplateInfo &TemplateInfo) {
1068511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  // static_assert-declaration
1069682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  if (Tok.is(tok::kw_static_assert)) {
107037b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    // FIXME: Check for templates
107197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
107297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    ParseStaticAssertDeclaration(DeclEnd);
1073682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1074682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
10751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1076682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  if (Tok.is(tok::kw_template)) {
10771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(!TemplateInfo.TemplateParams &&
107837b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor           "Nested template improperly parsed?");
107997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
10801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd,
10814d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                         AS);
1082682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1083682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
10845aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson
1085bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  // Handle:  member-declaration ::= '__extension__' member-declaration
1086bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  if (Tok.is(tok::kw___extension__)) {
1087bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    // __extension__ silences extension warnings in the subexpression.
1088bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
1089bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ConsumeToken();
109037b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    return ParseCXXClassMemberDeclaration(AS, TemplateInfo);
1091bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  }
10929cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
1093bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  CXX0XAttributeList AttrList;
1094bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // Optional C++0x attribute-specifier
1095bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
1096bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = ParseCXX0XAttributes();
1097bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1098bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
10999cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_using)) {
110037b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    // FIXME: Check for template aliases
1101bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1102bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (AttrList.HasAttr)
1103bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      Diag(AttrList.Range.getBegin(), diag::err_attributes_not_allowed)
1104bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        << AttrList.Range;
11051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11069cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    // Eat 'using'.
11079cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SourceLocation UsingLoc = ConsumeToken();
11089cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
11099cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    if (Tok.is(tok::kw_namespace)) {
11109cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      Diag(UsingLoc, diag::err_using_namespace_in_class);
11119cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SkipUntil(tok::semi, true, true);
11129cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    }
11139cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    else {
11149cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SourceLocation DeclEnd;
11159cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      // Otherwise, it must be using-declaration.
1116595adc1795cc2c079ef5876100e01acd10a0504aAnders Carlsson      ParseUsingDeclaration(Declarator::MemberContext, UsingLoc, DeclEnd, AS);
11179cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    }
11189cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return;
11199cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
11209cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
11214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  SourceLocation DSStart = Tok.getLocation();
11224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // decl-specifier-seq:
11234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Parse the common declaration-specifiers piece.
112454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclSpec DS(*this);
1125bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  DS.AddAttributes(AttrList.AttrList);
112637b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor  ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class);
11274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1128dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  Action::MultiTemplateParamsArg TemplateParams(Actions,
1129dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
1130dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
1131dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
11324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::semi)) {
11334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
1134d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
113567d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    return;
11364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
113707952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
113854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext);
11394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11403a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis  if (Tok.isNot(tok::colon)) {
11413a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Parse the first declarator.
11423a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    ParseDeclarator(DeclaratorInfo);
11433a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Error parsing the declarator?
114410bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor    if (!DeclaratorInfo.hasName()) {
11453a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      // If so, skip until the semi-colon or a }.
11464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      SkipUntil(tok::r_brace, true);
11473a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (Tok.is(tok::semi))
11483a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeToken();
1149682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
11504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
11514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11521b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson    // If attributes exist after the declarator, but before an '{', parse them.
11531b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson    if (Tok.is(tok::kw___attribute)) {
11541b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson      SourceLocation Loc;
11551b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson      AttributeList *AttrList = ParseGNUAttributes(&Loc);
11561b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson      DeclaratorInfo.AddAttributes(AttrList, Loc);
11571b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson    }
11581b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson
11593a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // function-definition:
11607ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    if (Tok.is(tok::l_brace)
1161d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl        || (DeclaratorInfo.isFunctionDeclarator() &&
1162d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl            (Tok.is(tok::colon) || Tok.is(tok::kw_try)))) {
11633a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (!DeclaratorInfo.isFunctionDeclarator()) {
11643a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        Diag(Tok, diag::err_func_def_no_params);
11653a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
11663a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        SkipUntil(tok::r_brace, true);
1167682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
11683a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
11693a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis
11703a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
11713a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        Diag(Tok, diag::err_function_declared_typedef);
11723a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // This recovery skips the entire function body. It would be nice
11733a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // to simply call ParseCXXInlineMethodDef() below, however Sema
11743a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // assumes the declarator represents a function, not a typedef.
11753a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
11763a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        SkipUntil(tok::r_brace, true);
1177682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
11783a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
11794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
118037b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor      ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo);
1181682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
11823a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    }
11834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
11844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // member-declarator-list:
11864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator
11874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator-list ',' member-declarator
11884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1189682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup;
119015faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl  OwningExprResult BitfieldSize(Actions);
119115faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl  OwningExprResult Init(Actions);
1192e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl  bool Deleted = false;
11934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
11944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  while (1) {
11954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // member-declarator:
11964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   declarator pure-specifier[opt]
11974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   declarator constant-initializer[opt]
11984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   identifier[opt] ':' constant-expression
11994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
12004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::colon)) {
12014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
12020e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      BitfieldSize = ParseConstantExpression();
12030e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      if (BitfieldSize.isInvalid())
12044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        SkipUntil(tok::comma, true, true);
12054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
12061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // pure-specifier:
12084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   '= 0'
12094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //
12104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // constant-initializer:
12114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   '=' constant-expression
1212e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //
1213e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    // defaulted/deleted function-definition:
1214e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //   '=' 'default'                          [TODO]
1215e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //   '=' 'delete'
12164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
12174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::equal)) {
12184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
1219e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl      if (getLang().CPlusPlus0x && Tok.is(tok::kw_delete)) {
1220e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        ConsumeToken();
1221e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        Deleted = true;
1222e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl      } else {
1223e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        Init = ParseInitializer();
1224e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        if (Init.isInvalid())
1225e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl          SkipUntil(tok::comma, true, true);
1226e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl      }
12274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
12284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
12294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If attributes exist after the declarator, parse them.
1230ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    if (Tok.is(tok::kw___attribute)) {
1231ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      SourceLocation Loc;
1232bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttributeList *AttrList = ParseGNUAttributes(&Loc);
1233ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      DeclaratorInfo.AddAttributes(AttrList, Loc);
1234ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    }
12354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
123607952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // NOTE: If Sema is the Action module and declarator is an instance field,
1237682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    // this call will *not* return the created decl; It will return null.
123807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // See Sema::ActOnCXXMemberDeclarator for details.
123967d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall
124067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    DeclPtrTy ThisDecl;
124167d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    if (DS.isFriendSpecified()) {
1242bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall      // TODO: handle initializers, bitfields, 'delete'
1243bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall      ThisDecl = Actions.ActOnFriendFunctionDecl(CurScope, DeclaratorInfo,
1244bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall                                                 /*IsDefinition*/ false,
1245bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall                                                 move(TemplateParams));
124637b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    } else {
124767d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall      ThisDecl = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
124867d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  DeclaratorInfo,
124937b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor                                                  move(TemplateParams),
125067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  BitfieldSize.release(),
125167d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  Init.release(),
1252d1a7846699a82f85ff3ce6b2e383409537c3f5c5Sebastian Redl                                                  /*IsDefinition*/Deleted,
125367d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  Deleted);
125437b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    }
1255682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    if (ThisDecl)
1256682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      DeclsInGroup.push_back(ThisDecl);
12574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
125872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    if (DeclaratorInfo.isFunctionDeclarator() &&
12591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        DeclaratorInfo.getDeclSpec().getStorageClassSpec()
126072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor          != DeclSpec::SCS_typedef) {
1261d33133cdc1af466f9c276249b2621be03867888bEli Friedman      HandleMemberFunctionDefaultArgs(DeclaratorInfo, ThisDecl);
126272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    }
126372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor
126454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    DeclaratorInfo.complete(ThisDecl);
126554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
12664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If we don't have a comma, it is either the end of the list (a ';')
12674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // or an error, bail out.
12684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.isNot(tok::comma))
12694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
12701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Consume the comma.
12724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
12731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Parse the next declarator.
12754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    DeclaratorInfo.clear();
127615faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl    BitfieldSize = 0;
127715faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl    Init = 0;
1278e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    Deleted = false;
12791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Attributes are only allowed on the second declarator.
1281ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    if (Tok.is(tok::kw___attribute)) {
1282ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      SourceLocation Loc;
1283bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttributeList *AttrList = ParseGNUAttributes(&Loc);
1284ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      DeclaratorInfo.AddAttributes(AttrList, Loc);
1285ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    }
12864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
12873a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    if (Tok.isNot(tok::colon))
12883a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      ParseDeclarator(DeclaratorInfo);
12894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
12904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
12914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::semi)) {
12924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
1293c1dc653b08226c1d8e1732f9d8b03b82869900bcEli Friedman    Actions.FinalizeDeclaratorGroup(CurScope, DS, DeclsInGroup.data(),
1294682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner                                    DeclsInGroup.size());
1295682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
12964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
12974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
12984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  Diag(Tok, diag::err_expected_semi_decl_list);
12994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Skip to end of block or statement
13004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  SkipUntil(tok::r_brace, true, true);
13014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::semi))
13024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
1303682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  return;
13044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
13054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition.
13074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
13084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-specification:
13094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declaration member-specification[opt]
13104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         access-specifier ':' member-specification[opt]
13114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
13124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidisvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
1313b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner                                         unsigned TagType, DeclPtrTy TagDecl) {
131431fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta  assert((TagType == DeclSpec::TST_struct ||
13154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis         TagType == DeclSpec::TST_union  ||
131631fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta         TagType == DeclSpec::TST_class) && "Invalid TagType!");
13174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
131849f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner  PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
131949f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner                                        PP.getSourceManager(),
132049f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner                                        "parsing struct/union/class body");
13211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  SourceLocation LBraceLoc = ConsumeBrace();
13234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13246569d68745c8213709740337d2be52b031384f58Douglas Gregor  // Determine whether this is a top-level (non-nested) class.
13251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool TopLevelClass = ClassStack.empty() ||
13266569d68745c8213709740337d2be52b031384f58Douglas Gregor    CurScope->isInCXXInlineMethodScope();
13274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Enter a scope for the class.
13293218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
13304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13316569d68745c8213709740337d2be52b031384f58Douglas Gregor  // Note that we are parsing a new (potentially-nested) class definition.
13326569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingClassDefinition ParsingDef(*this, TagDecl, TopLevelClass);
13336569d68745c8213709740337d2be52b031384f58Douglas Gregor
1334ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  if (TagDecl)
1335ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    Actions.ActOnTagStartDefinition(CurScope, TagDecl);
1336ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  else {
1337ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    SkipUntil(tok::r_brace, false, false);
1338ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    return;
1339ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  }
13404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // C++ 11p3: Members of a class defined with the keyword class are private
13424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // by default. Members of a class defined with the keywords struct or union
13434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // are public by default.
13444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  AccessSpecifier CurAS;
13454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (TagType == DeclSpec::TST_class)
13464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_private;
13474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  else
13484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_public;
13494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // While we still have something to read, read the member-declarations.
13514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
13524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Each iteration of this loop reads one member-declaration.
13531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Check for extraneous top-level semicolon.
13554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::semi)) {
1356c2253f5ca170984fcd4f30f8823148e8cb71336bChris Lattner      Diag(Tok, diag::ext_extra_struct_semi)
135729d9c1adfadf65e2d847d44bec37746844b9e0e3Chris Lattner        << CodeModificationHint::CreateRemoval(Tok.getLocation());
13584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
13594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      continue;
13604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
13614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    AccessSpecifier AS = getAccessSpecifierIfPresent();
13634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (AS != AS_none) {
13644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      // Current token is a C++ access specifier.
13654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      CurAS = AS;
13664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
13674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ExpectAndConsume(tok::colon, diag::err_expected_colon);
13684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      continue;
13694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
13704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
137137b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    // FIXME: Make sure we don't have a template here.
13721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Parse all the comma separated declarators.
13744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ParseCXXClassMemberDeclaration(CurAS);
13754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
13761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
13781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  AttributeList *AttrList = 0;
13804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // If attributes exist after class contents, parse them.
13814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::kw___attribute))
1382bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = ParseGNUAttributes(); // FIXME: where should I put them?
13834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl,
13854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis                                            LBraceLoc, RBraceLoc);
13864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // C++ 9.2p2: Within the class member-specification, the class is regarded as
13884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // complete within function bodies, default arguments,
13894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // exception-specifications, and constructor ctor-initializers (including
13904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // such things in nested classes).
13914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //
139272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor  // FIXME: Only function bodies and constructor ctor-initializers are
139372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor  // parsed correctly, fix the rest.
13946569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (TopLevelClass) {
13954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // We are not inside a nested class. This class and its nested classes
139672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    // are complete and we can parse the delayed portions of method
139772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    // declarations and the lexed inline method definitions.
13986569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDeclarations(getCurrentClass());
13996569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDefs(getCurrentClass());
14004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
14014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
14024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Leave the class scope.
14036569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingDef.Pop();
14048935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ClassScope.Exit();
14054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
140607a5b282fbe719986df9ed05543081ea0ed94aa5Argyrios Kyrtzidis  Actions.ActOnTagFinishDefinition(CurScope, TagDecl, RBraceLoc);
14074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
14087ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
14097ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer,
14107ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a
14117ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers
14127ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below:
14137ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
14147ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code
14157ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { };
14167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base {
14177ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   int x;
14187ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   float f;
14197ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public:
14207ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   Derived(float f) : Base(), x(17), f(f) { }
14217ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// };
14227ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode
14237ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
14241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  ctor-initializer:
14251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///          ':' mem-initializer-list
14267ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
14271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  mem-initializer-list:
14281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///          mem-initializer
14291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///          mem-initializer , mem-initializer-list
1430b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattnervoid Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) {
14317ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
14327ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
14337ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation ColonLoc = ConsumeToken();
14341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  llvm::SmallVector<MemInitTy*, 4> MemInitializers;
14361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  do {
14387ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
14395ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor    if (!MemInit.isInvalid())
14405ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor      MemInitializers.push_back(MemInit.get());
14417ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
14427ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    if (Tok.is(tok::comma))
14437ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      ConsumeToken();
14447ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    else if (Tok.is(tok::l_brace))
14457ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
14467ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    else {
14477ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      // Skip over garbage, until we get to '{'.  Don't eat the '{'.
1448d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl      Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
14497ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      SkipUntil(tok::l_brace, true, true);
14507ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
14517ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    }
14527ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  } while (true);
14537ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
14541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc,
1455beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad                               MemInitializers.data(), MemInitializers.size());
14567ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
14577ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
14587ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is
14597ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one
14607ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See
14617ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example.
14627ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
14637ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer:
14647ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         mem-initializer-id '(' expression-list[opt] ')'
14651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
14667ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id:
14677ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         '::'[opt] nested-name-specifier[opt] class-name
14687ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         identifier
1469b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris LattnerParser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
1470bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  // parse '::'[opt] nested-name-specifier[opt]
1471bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  CXXScopeSpec SS;
14722dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
1473961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  TypeTy *TemplateTypeTy = 0;
1474961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (Tok.is(tok::annot_template_id)) {
1475961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    TemplateIdAnnotation *TemplateId
1476961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
1477961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    if (TemplateId->Kind == TNK_Type_template) {
1478961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      AnnotateTemplateIdTokenAsType(&SS);
1479961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
1480961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      TemplateTypeTy = Tok.getAnnotationValue();
1481961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    }
1482961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    // FIXME. May need to check for TNK_Dependent_template as well.
1483961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  }
1484961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (!TemplateTypeTy && Tok.isNot(tok::identifier)) {
14851ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_member_or_base_name);
14867ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
14877ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
14881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14897ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Get the identifier. This may be a member name or a class name,
14907ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // but we'll let the semantic analysis determine which it is.
1491961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  IdentifierInfo *II = Tok.is(tok::identifier) ? Tok.getIdentifierInfo() : 0;
14927ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation IdLoc = ConsumeToken();
14937ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
14947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Parse the '('.
14957ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  if (Tok.isNot(tok::l_paren)) {
14961ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen);
14977ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
14987ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
14997ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation LParenLoc = ConsumeParen();
15007ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
15017ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Parse the optional expression-list.
1502a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl  ExprVector ArgExprs(Actions);
15037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  CommaLocsTy CommaLocs;
15047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
15057ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    SkipUntil(tok::r_paren);
15067ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
15077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
15087ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
15097ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
15107ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
1511961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, SS, II,
1512961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian                                     TemplateTypeTy, IdLoc,
1513a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl                                     LParenLoc, ArgExprs.take(),
1514beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad                                     ArgExprs.size(), CommaLocs.data(),
1515beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad                                     RParenLoc);
15167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
15170fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
15180fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// ParseExceptionSpecification - Parse a C++ exception-specification
15190fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// (C++ [except.spec]).
15200fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
1521a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       exception-specification:
1522a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         'throw' '(' type-id-list [opt] ')'
1523a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS]    'throw' '(' '...' ')'
15241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
1525a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       type-id-list:
1526a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         type-id
1527a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         type-id-list ',' type-id
15280fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
15297dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redlbool Parser::ParseExceptionSpecification(SourceLocation &EndLoc,
1530ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl                                         llvm::SmallVector<TypeTy*, 2>
1531ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl                                             &Exceptions,
1532ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl                                         llvm::SmallVector<SourceRange, 2>
1533ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl                                             &Ranges,
15347dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl                                         bool &hasAnyExceptionSpec) {
15350fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  assert(Tok.is(tok::kw_throw) && "expected throw");
15361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15370fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  SourceLocation ThrowLoc = ConsumeToken();
15381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15390fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  if (!Tok.is(tok::l_paren)) {
15400fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor    return Diag(Tok, diag::err_expected_lparen_after) << "throw";
15410fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
15420fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  SourceLocation LParenLoc = ConsumeParen();
15430fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
1544a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // Parse throw(...), a Microsoft extension that means "this function
1545a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // can throw anything".
1546a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  if (Tok.is(tok::ellipsis)) {
15477dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl    hasAnyExceptionSpec = true;
1548a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    SourceLocation EllipsisLoc = ConsumeToken();
1549a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    if (!getLang().Microsoft)
1550a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor      Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
1551ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1552a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    return false;
1553a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  }
1554a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor
15550fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  // Parse the sequence of type-ids.
1556ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl  SourceRange Range;
15570fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  while (Tok.isNot(tok::r_paren)) {
1558ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    TypeResult Res(ParseTypeName(&Range));
1559ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    if (!Res.isInvalid()) {
15607dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl      Exceptions.push_back(Res.get());
1561ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl      Ranges.push_back(Range);
1562ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    }
15630fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor    if (Tok.is(tok::comma))
15640fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      ConsumeToken();
15657dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl    else
15660fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      break;
15670fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
15680fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
1569ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl  EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
15700fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  return false;
15710fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor}
15726569d68745c8213709740337d2be52b031384f58Douglas Gregor
15736569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief We have just started parsing the definition of a new class,
15746569d68745c8213709740337d2be52b031384f58Douglas Gregor/// so push that class onto our stack of classes that is currently
15756569d68745c8213709740337d2be52b031384f58Douglas Gregor/// being parsed.
15766569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::PushParsingClass(DeclPtrTy ClassDecl, bool TopLevelClass) {
15771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  assert((TopLevelClass || !ClassStack.empty()) &&
15786569d68745c8213709740337d2be52b031384f58Douglas Gregor         "Nested class without outer class");
15796569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.push(new ParsingClass(ClassDecl, TopLevelClass));
15806569d68745c8213709740337d2be52b031384f58Douglas Gregor}
15816569d68745c8213709740337d2be52b031384f58Douglas Gregor
15826569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Deallocate the given parsed class and all of its nested
15836569d68745c8213709740337d2be52b031384f58Douglas Gregor/// classes.
15846569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
15856569d68745c8213709740337d2be52b031384f58Douglas Gregor  for (unsigned I = 0, N = Class->NestedClasses.size(); I != N; ++I)
15866569d68745c8213709740337d2be52b031384f58Douglas Gregor    DeallocateParsedClasses(Class->NestedClasses[I]);
15876569d68745c8213709740337d2be52b031384f58Douglas Gregor  delete Class;
15886569d68745c8213709740337d2be52b031384f58Douglas Gregor}
15896569d68745c8213709740337d2be52b031384f58Douglas Gregor
15906569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Pop the top class of the stack of classes that are
15916569d68745c8213709740337d2be52b031384f58Douglas Gregor/// currently being parsed.
15926569d68745c8213709740337d2be52b031384f58Douglas Gregor///
15936569d68745c8213709740337d2be52b031384f58Douglas Gregor/// This routine should be called when we have finished parsing the
15946569d68745c8213709740337d2be52b031384f58Douglas Gregor/// definition of a class, but have not yet popped the Scope
15956569d68745c8213709740337d2be52b031384f58Douglas Gregor/// associated with the class's definition.
15966569d68745c8213709740337d2be52b031384f58Douglas Gregor///
15976569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \returns true if the class we've popped is a top-level class,
15986569d68745c8213709740337d2be52b031384f58Douglas Gregor/// false otherwise.
15996569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::PopParsingClass() {
16006569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");
16011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16026569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingClass *Victim = ClassStack.top();
16036569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.pop();
16046569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (Victim->TopLevelClass) {
16056569d68745c8213709740337d2be52b031384f58Douglas Gregor    // Deallocate all of the nested classes of this class,
16066569d68745c8213709740337d2be52b031384f58Douglas Gregor    // recursively: we don't need to keep any of this information.
16076569d68745c8213709740337d2be52b031384f58Douglas Gregor    DeallocateParsedClasses(Victim);
16086569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
16091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
16106569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Missing top-level class?");
16116569d68745c8213709740337d2be52b031384f58Douglas Gregor
16126569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (Victim->MethodDecls.empty() && Victim->MethodDefs.empty() &&
16136569d68745c8213709740337d2be52b031384f58Douglas Gregor      Victim->NestedClasses.empty()) {
16146569d68745c8213709740337d2be52b031384f58Douglas Gregor    // The victim is a nested class, but we will not need to perform
16156569d68745c8213709740337d2be52b031384f58Douglas Gregor    // any processing after the definition of this class since it has
16166569d68745c8213709740337d2be52b031384f58Douglas Gregor    // no members whose handling was delayed. Therefore, we can just
16176569d68745c8213709740337d2be52b031384f58Douglas Gregor    // remove this nested class.
16186569d68745c8213709740337d2be52b031384f58Douglas Gregor    delete Victim;
16196569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
16206569d68745c8213709740337d2be52b031384f58Douglas Gregor  }
16216569d68745c8213709740337d2be52b031384f58Douglas Gregor
16226569d68745c8213709740337d2be52b031384f58Douglas Gregor  // This nested class has some members that will need to be processed
16236569d68745c8213709740337d2be52b031384f58Douglas Gregor  // after the top-level class is completely defined. Therefore, add
16246569d68745c8213709740337d2be52b031384f58Douglas Gregor  // it to the list of nested classes within its parent.
16256569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(CurScope->isClassScope() && "Nested class outside of class scope?");
16266569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.top()->NestedClasses.push_back(Victim);
16276569d68745c8213709740337d2be52b031384f58Douglas Gregor  Victim->TemplateScope = CurScope->getParent()->isTemplateParamScope();
16286569d68745c8213709740337d2be52b031384f58Douglas Gregor}
1629bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1630bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// ParseCXX0XAttributes - Parse a C++0x attribute-specifier. Currently only
1631bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// parses standard attributes.
1632bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1633bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-specifier:
1634bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' '[' attribute-list ']' ']'
1635bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1636bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-list:
1637bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute[opt]
1638bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-list ',' attribute[opt]
1639bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1640bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute:
1641bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-token attribute-argument-clause[opt]
1642bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1643bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-token:
1644bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
1645bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-scoped-token
1646bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1647bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-scoped-token:
1648bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-namespace '::' identifier
1649bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1650bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-namespace:
1651bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
1652bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1653bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-argument-clause:
1654bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
1655bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1656bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] balanced-token-seq:
1657bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token
1658bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token-seq balanced-token
1659bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1660bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] balanced-token:
1661bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
1662bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' balanced-token-seq ']'
1663bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '{' balanced-token-seq '}'
1664bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         any token but '(', ')', '[', ']', '{', or '}'
1665bbd37c62e34db3f5a95c899723484a76c71d7757Sean HuntCXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
1666bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
1667bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      && "Not a C++0x attribute list");
1668bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1669bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  SourceLocation StartLoc = Tok.getLocation(), Loc;
1670bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  AttributeList *CurrAttr = 0;
1671bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1672bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
1673bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
1674bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1675bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Tok.is(tok::comma)) {
1676bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Diag(Tok.getLocation(), diag::err_expected_ident);
1677bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    ConsumeToken();
1678bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1679bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1680bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  while (Tok.is(tok::identifier) || Tok.is(tok::comma)) {
1681bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // attribute not present
1682bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::comma)) {
1683bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
1684bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      continue;
1685bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
1686bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1687bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    IdentifierInfo *ScopeName = 0, *AttrName = Tok.getIdentifierInfo();
1688bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceLocation ScopeLoc, AttrLoc = ConsumeToken();
1689bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1690bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // scoped attribute
1691bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::coloncolon)) {
1692bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
1693bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1694bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      if (!Tok.is(tok::identifier)) {
1695bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        Diag(Tok.getLocation(), diag::err_expected_ident);
1696bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        SkipUntil(tok::r_square, tok::comma, true, true);
1697bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        continue;
1698bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
1699bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1700bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ScopeName = AttrName;
1701bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ScopeLoc = AttrLoc;
1702bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1703bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttrName = Tok.getIdentifierInfo();
1704bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttrLoc = ConsumeToken();
1705bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
1706bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1707bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    bool AttrParsed = false;
1708bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // No scoped names are supported; ideally we could put all non-standard
1709bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // attributes into namespaces.
1710bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (!ScopeName) {
1711bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      switch(AttributeList::getKind(AttrName))
1712bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      {
1713bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // No arguments
17147725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_base_check:
17157725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_carries_dependency:
1716bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      case AttributeList::AT_final:
17177725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_hiding:
17187725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_noreturn:
17197725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_override: {
1720bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        if (Tok.is(tok::l_paren)) {
1721bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          Diag(Tok.getLocation(), diag::err_cxx0x_attribute_forbids_arguments)
1722bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt            << AttrName->getName();
1723bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          break;
1724bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        }
1725bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1726bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        CurrAttr = new AttributeList(AttrName, AttrLoc, 0, AttrLoc, 0,
1727bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                     SourceLocation(), 0, 0, CurrAttr, false,
1728bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                     true);
1729bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        AttrParsed = true;
1730bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        break;
1731bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
1732bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1733bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // One argument; must be a type-id or assignment-expression
1734bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      case AttributeList::AT_aligned: {
1735bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        if (Tok.isNot(tok::l_paren)) {
1736bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          Diag(Tok.getLocation(), diag::err_cxx0x_attribute_requires_arguments)
1737bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt            << AttrName->getName();
1738bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          break;
1739bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        }
1740bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        SourceLocation ParamLoc = ConsumeParen();
1741bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1742bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        OwningExprResult ArgExpr = ParseCXX0XAlignArgument(ParamLoc);
1743bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1744bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        MatchRHSPunctuation(tok::r_paren, ParamLoc);
1745bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1746bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        ExprVector ArgExprs(Actions);
1747bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        ArgExprs.push_back(ArgExpr.release());
1748bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        CurrAttr = new AttributeList(AttrName, AttrLoc, 0, AttrLoc,
1749bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                     0, ParamLoc, ArgExprs.take(), 1, CurrAttr,
1750bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                     false, true);
1751bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1752bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        AttrParsed = true;
1753bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        break;
1754bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
1755bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1756bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // Silence warnings
1757bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      default: break;
1758bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
1759bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
1760bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1761bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // Skip the entire parameter clause, if any
1762bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (!AttrParsed && Tok.is(tok::l_paren)) {
1763bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeParen();
1764bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // SkipUntil maintains the balancedness of tokens.
1765bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      SkipUntil(tok::r_paren, false);
1766bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
1767bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1768bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1769bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
1770bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
1771bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  Loc = Tok.getLocation();
1772bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
1773bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
1774bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1775bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  CXX0XAttributeList Attr (CurrAttr, SourceRange(StartLoc, Loc), true);
1776bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  return Attr;
1777bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1778bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1779bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// ParseCXX0XAlignArgument - Parse the argument to C++0x's [[align]]
1780bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute.
1781bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1782bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// FIXME: Simply returns an alignof() expression if the argument is a
1783bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// type. Ideally, the type should be propagated directly into Sema.
1784bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1785bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] 'align' '(' type-id ')'
1786bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] 'align' '(' assignment-expression ')'
1787bbd37c62e34db3f5a95c899723484a76c71d7757Sean HuntParser::OwningExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) {
1788bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (isTypeIdInParens()) {
1789bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    EnterExpressionEvaluationContext Unevaluated(Actions,
1790bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                                  Action::Unevaluated);
1791bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceLocation TypeLoc = Tok.getLocation();
1792bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    TypeTy *Ty = ParseTypeName().get();
1793bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceRange TypeRange(Start, Tok.getLocation());
1794bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return Actions.ActOnSizeOfAlignOfExpr(TypeLoc, false, true, Ty,
1795bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                              TypeRange);
1796bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  } else
1797bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return ParseConstantExpression();
1798bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
1799