ParseDeclCXX.cpp revision e6563256a4b3b9fee70ce3335d28406607c1faaf
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);
53dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
5449f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
55193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
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.
671e37765c9257ef1d051f54a674eaa964bdba9693Ted Kremenek  llvm::OwningPtr<AttributeList> AttrList;
686a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor  if (Tok.is(tok::kw___attribute)) {
696a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor    attrTok = Tok;
706a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor
718f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner    // FIXME: save these somewhere.
721e37765c9257ef1d051f54a674eaa964bdba9693Ted Kremenek    AttrList.reset(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
9095f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor  if (CurScope->isClassScope() || CurScope->isTemplateParamScope() ||
9195f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor      CurScope->isInObjcMethodScope() || CurScope->getBlockParent() ||
9295f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor      CurScope->getFnParent()) {
9395f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor    Diag(LBrace, diag::err_namespace_nonnamespace_scope);
9495f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor    SkipUntil(tok::r_brace, false);
9595f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor    return DeclPtrTy();
9695f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor  }
9795f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor
985144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Enter a scope for the namespace.
995144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  ParseScope NamespaceScope(this, Scope::DeclScope);
1002d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
1015144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  DeclPtrTy NamespcDecl =
1021e37765c9257ef1d051f54a674eaa964bdba9693Ted Kremenek    Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace,
1031e37765c9257ef1d051f54a674eaa964bdba9693Ted Kremenek                                   AttrList.get());
1042d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
1055144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions,
1065144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner                                        PP.getSourceManager(),
1075144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner                                        "parsing namespace");
1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
109bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
110bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    CXX0XAttributeList Attr;
111bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
112bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      Attr = ParseCXX0XAttributes();
113bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    ParseExternalDeclaration(Attr);
114bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1165144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  // Leave the namespace scope.
1175144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  NamespaceScope.Exit();
1188ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis
11997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBrace);
12097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  Actions.ActOnFinishNamespaceDef(NamespcDecl, RBraceLoc);
1212d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis
12297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = RBraceLoc;
1235144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner  return NamespcDecl;
1248f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner}
125c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
126f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// ParseNamespaceAlias - Parse the part after the '=' in a namespace
127f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// alias definition.
128f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson///
12903bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders CarlssonParser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                              SourceLocation AliasLoc,
13197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                              IdentifierInfo *Alias,
13297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                              SourceLocation &DeclEnd) {
133f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  assert(Tok.is(tok::equal) && "Not equal token");
1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
135f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  ConsumeToken(); // eat the '='.
1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13749f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
13849f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor    Actions.CodeCompleteNamespaceAliasDecl(CurScope);
139dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
14049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
141193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
142f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  CXXScopeSpec SS;
143f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse (optional) nested-name-specifier.
144be1ea44be73facdb60edae34c2fb1a38dafcb28cChris Lattner  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
145f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
146f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
147f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    Diag(Tok, diag::err_expected_namespace_name);
148f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    // Skip to end of the definition and eat the ';'.
149f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson    SkipUntil(tok::semi);
150b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
151f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  }
152f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
153f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Parse identifier.
15403bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  IdentifierInfo *Ident = Tok.getIdentifierInfo();
15503bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson  SourceLocation IdentLoc = ConsumeToken();
1561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
157f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson  // Eat the ';'.
15897144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
1596869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name,
1606869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner                   "", tok::semi);
1611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return Actions.ActOnNamespaceAliasDef(CurScope, NamespaceLoc, AliasLoc, Alias,
16303bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson                                        SS, IdentLoc, Ident);
164f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson}
165f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson
166c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal
167c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen.
168c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
169c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///       linkage-specification: [C++ 7.5p2: dcl.link]
170c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal '{' declaration-seq[opt] '}'
171c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///         'extern' string-literal declaration
172c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner///
1733acd9aaa4ddd14afecb4f1c02ca6f585a6d51849Fariborz JahanianParser::DeclPtrTy Parser::ParseLinkage(ParsingDeclSpec &DS,
1743acd9aaa4ddd14afecb4f1c02ca6f585a6d51849Fariborz Jahanian                                       unsigned Context) {
175c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor  assert(Tok.is(tok::string_literal) && "Not a string literal!");
176193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  llvm::SmallString<8> LangBuffer;
177c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  // LangBuffer is guaranteed to be big enough.
178453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  bool Invalid = false;
179453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  llvm::StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid);
180453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor  if (Invalid)
181453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor    return DeclPtrTy();
182c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
183c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner  SourceLocation Loc = ConsumeStringToken();
184c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
185074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  ParseScope LinkageScope(this, Scope::DeclScope);
1861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  DeclPtrTy LinkageSpec
1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    = Actions.ActOnStartLinkageSpecification(CurScope,
188074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                             /*FIXME: */SourceLocation(),
189d56638180014e60538cd666cd11fde6d4698e051Benjamin Kramer                                             Loc, Lang,
1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                       Tok.is(tok::l_brace)? Tok.getLocation()
191074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                           : SourceLocation());
192074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
193bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  CXX0XAttributeList Attr;
194bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
195bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Attr = ParseCXX0XAttributes();
196bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
197193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
198074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (Tok.isNot(tok::l_brace)) {
1993acd9aaa4ddd14afecb4f1c02ca6f585a6d51849Fariborz Jahanian    ParseDeclarationOrFunctionDefinition(DS, Attr.AttrList);
2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec,
201074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor                                                   SourceLocation());
2021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
203f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor
20463a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor  DS.abort();
20563a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor
206bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Attr.HasAttr)
207bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
208bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      << Attr.Range;
209bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
210f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  SourceLocation LBrace = ConsumeBrace();
211f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
212bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    CXX0XAttributeList Attr;
213bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
214bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      Attr = ParseCXX0XAttributes();
215bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    ParseExternalDeclaration(Attr);
216f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  }
217c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner
218f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor  SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
219074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, RBrace);
220c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner}
221e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
222f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
223f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'.
22497144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris LattnerParser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
225bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                                     SourceLocation &DeclEnd,
226bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                                     CXX0XAttributeList Attr) {
227f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_using) && "Not using token");
228f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
229f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'using'.
230f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation UsingLoc = ConsumeToken();
231f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
23249f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
23349f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor    Actions.CodeCompleteUsing(CurScope);
234dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
23549f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
236193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
2372f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner  if (Tok.is(tok::kw_namespace))
238f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // Next token after 'using' is 'namespace' so it must be using-directive
239bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return ParseUsingDirective(Context, UsingLoc, DeclEnd, Attr.AttrList);
240bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
241bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Attr.HasAttr)
242bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
243bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      << Attr.Range;
2442f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner
2452f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner  // Otherwise, it must be using-declaration.
246bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // Ignore illegal attributes (the caller should already have issued an error.
24797144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  return ParseUsingDeclaration(Context, UsingLoc, DeclEnd);
248f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
249f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
250f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes
251f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed.
252f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
253f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       using-directive: [C++ 7.3.p4: namespace.udir]
254f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
255f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name ;
256f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive:
257f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///        'using' 'namespace' ::[opt] nested-name-specifier[opt]
258f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///                 namespace-name attributes[opt] ;
259f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
260b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris LattnerParser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
26197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                              SourceLocation UsingLoc,
262bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                              SourceLocation &DeclEnd,
263bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                              AttributeList *Attr) {
264f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
265f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
266f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Eat 'namespace'.
267f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation NamespcLoc = ConsumeToken();
268f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
26949f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  if (Tok.is(tok::code_completion)) {
27049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor    Actions.CodeCompleteUsingDirective(CurScope);
271dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
27249f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor  }
273193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
274f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  CXXScopeSpec SS;
275f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse (optional) nested-name-specifier.
276be1ea44be73facdb60edae34c2fb1a38dafcb28cChris Lattner  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
277f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
278f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  IdentifierInfo *NamespcName = 0;
279f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  SourceLocation IdentLoc = SourceLocation();
280f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
281f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  // Parse namespace-name.
282823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
283f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    Diag(Tok, diag::err_expected_namespace_name);
284f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // If there was invalid namespace name, skip to end of decl, and eat ';'.
285f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    SkipUntil(tok::semi);
286f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor    // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
287b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
288f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  }
2891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
290823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse identifier.
291823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  NamespcName = Tok.getIdentifierInfo();
292823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  IdentLoc = ConsumeToken();
2931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
294823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Parse (optional) attributes (most likely GNU strong-using extension).
295bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  bool GNUAttr = false;
296bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Tok.is(tok::kw___attribute)) {
297bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    GNUAttr = true;
298bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Attr = addAttributeLists(Attr, ParseGNUAttributes());
299bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
3001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
301823c44e6d73141f642e207980b4021ddcf09897bChris Lattner  // Eat ';'.
30297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
3036869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner  ExpectAndConsume(tok::semi,
304bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                   GNUAttr ? diag::err_expected_semi_after_attribute_list :
3056869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner                   diag::err_expected_semi_after_namespace_name, "", tok::semi);
306f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
307f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor  return Actions.ActOnUsingDirective(CurScope, UsingLoc, NamespcLoc, SS,
308bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                      IdentLoc, NamespcName, Attr);
309f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
310f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
311f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that
312f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' was already seen.
313f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
314f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///     using-declaration: [C++ 7.3.p3: namespace.udecl]
315f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///       'using' 'typename'[opt] ::[opt] nested-name-specifier
3169cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///               unqualified-id
3179cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor///       'using' :: unqualified-id
318f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor///
319b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris LattnerParser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
32097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner                                                SourceLocation UsingLoc,
321595adc1795cc2c079ef5876100e01acd10a0504aAnders Carlsson                                                SourceLocation &DeclEnd,
322595adc1795cc2c079ef5876100e01acd10a0504aAnders Carlsson                                                AccessSpecifier AS) {
3239cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  CXXScopeSpec SS;
3247ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall  SourceLocation TypenameLoc;
3259cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  bool IsTypeName;
3269cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3279cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Ignore optional 'typename'.
32812c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // FIXME: This is wrong; we should parse this as a typename-specifier.
3299cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_typename)) {
3307ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall    TypenameLoc = Tok.getLocation();
3319cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    ConsumeToken();
3329cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = true;
3339cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
3349cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  else
3359cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    IsTypeName = false;
3369cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3379cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Parse nested-name-specifier.
338be1ea44be73facdb60edae34c2fb1a38dafcb28cChris Lattner  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
3399cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
3409cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Check nested-name specifier.
3419cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (SS.isInvalid()) {
3429cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
3439cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return DeclPtrTy();
3449cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
3451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
346193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  // Parse the unqualified-id. We allow parsing of both constructor and
34712c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // destructor names and allow the action module to diagnose any semantic
34812c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  // errors.
34912c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor  UnqualifiedId Name;
350193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  if (ParseUnqualifiedId(SS,
35112c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*EnteringContext=*/false,
35212c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         /*AllowDestructorName=*/true,
353193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                         /*AllowConstructorName=*/true,
354193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                         /*ObjectType=*/0,
35512c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                         Name)) {
3569cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SkipUntil(tok::semi);
3579cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return DeclPtrTy();
3589cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
359193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
3609cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Parse (optional) attributes (most likely GNU strong-using extension).
3611e37765c9257ef1d051f54a674eaa964bdba9693Ted Kremenek  llvm::OwningPtr<AttributeList> AttrList;
3629cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw___attribute))
3631e37765c9257ef1d051f54a674eaa964bdba9693Ted Kremenek    AttrList.reset(ParseGNUAttributes());
3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3659cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  // Eat ';'.
3669cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  DeclEnd = Tok.getLocation();
3679cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
368193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                   AttrList ? "attributes list" : "using declaration",
36912c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor                   tok::semi);
3709cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
37160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  return Actions.ActOnUsingDeclaration(CurScope, AS, true, UsingLoc, SS, Name,
3721e37765c9257ef1d051f54a674eaa964bdba9693Ted Kremenek                                       AttrList.get(), IsTypeName, TypenameLoc);
373f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor}
374f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor
375511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
376511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
377511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///      static_assert-declaration:
378511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///        static_assert ( constant-expression  ,  string-literal  ) ;
379511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson///
38097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris LattnerParser::DeclPtrTy Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
381511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
382511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation StaticAssertLoc = ConsumeToken();
3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
384511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (Tok.isNot(tok::l_paren)) {
385511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_lparen);
386b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
387511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
389511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  SourceLocation LParenLoc = ConsumeParen();
390e0762c92110dfdcdd207db461a4ea17afd168f1eDouglas Gregor
391511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  OwningExprResult AssertExpr(ParseConstantExpression());
392511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (AssertExpr.isInvalid()) {
393511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    SkipUntil(tok::semi);
394b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
395511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
3961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
397ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
398b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
399ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson
400511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  if (Tok.isNot(tok::string_literal)) {
401511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    Diag(Tok, diag::err_expected_string_literal);
402511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson    SkipUntil(tok::semi);
403b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
404511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  }
4051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
406511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  OwningExprResult AssertMessage(ParseStringLiteralExpression());
4071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (AssertMessage.isInvalid())
408b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    return DeclPtrTy();
409511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
41094b15fbc3a10cdfb1639528a8a773b66a1e7cd9eAnders Carlsson  MatchRHSPunctuation(tok::r_paren, LParenLoc);
4111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
41297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner  DeclEnd = Tok.getLocation();
413511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert);
414511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
4151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, move(AssertExpr),
41694b15fbc3a10cdfb1639528a8a773b66a1e7cd9eAnders Carlsson                                              move(AssertMessage));
417511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson}
418511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson
4196fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// ParseDecltypeSpecifier - Parse a C++0x decltype specifier.
4206fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
4216fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 'decltype' ( expression )
4226fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson///
4236fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlssonvoid Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
4246fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  assert(Tok.is(tok::kw_decltype) && "Not a decltype specifier");
4256fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
4266fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation StartLoc = ConsumeToken();
4276fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation LParenLoc = Tok.getLocation();
4281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
4306fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson                       "decltype")) {
4316fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    SkipUntil(tok::r_paren);
4326fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
4336fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  }
4341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4356fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Parse the expression
4361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4376fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // C++0x [dcl.type.simple]p4:
4386fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  //   The operand of the decltype specifier is an unevaluated operand.
4396fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  EnterExpressionEvaluationContext Unevaluated(Actions,
4406fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson                                               Action::Unevaluated);
4416fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  OwningExprResult Result = ParseExpression();
4426fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (Result.isInvalid()) {
4436fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    SkipUntil(tok::r_paren);
4446fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
4456fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  }
4461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4476fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Match the ')'
4486fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  SourceLocation RParenLoc;
4496fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (Tok.is(tok::r_paren))
4506fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    RParenLoc = ConsumeParen();
4516fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  else
4526fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    MatchRHSPunctuation(tok::r_paren, LParenLoc);
4531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4546fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  if (RParenLoc.isInvalid())
4556fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson    return;
4566fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
4576fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  const char *PrevSpec = 0;
458fec54013fcd0eb72642741584ca04c1bc292bef8John McCall  unsigned DiagID;
4596fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson  // Check for duplicate type specifiers (e.g. "int decltype(a)").
4601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec,
461fec54013fcd0eb72642741584ca04c1bc292bef8John McCall                         DiagID, Result.release()))
462fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
4636fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson}
4646fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson
46542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// ParseClassName - Parse a C++ class-name, which names a class. Note
46642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// that we only check that the result names a type; semantic analysis
46742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// will need to verify that the type names a class. The result is
4687f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor/// either a type or NULL, depending on whether a type name was
46942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// found.
47042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///
47142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///       class-name: [C++ 9.1]
47242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor///         identifier
4737f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor///         simple-template-id
4741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
47531a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas GregorParser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
4769ab14541716928894821cf5d53d6b4c95ffdf3a3Jeffrey Yasskin                                          CXXScopeSpec *SS) {
4777f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  // Check whether we have a template-id that names a type.
4787f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  if (Tok.is(tok::annot_template_id)) {
4791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    TemplateIdAnnotation *TemplateId
4807f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
481d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor    if (TemplateId->Kind == TNK_Type_template ||
482d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor        TemplateId->Kind == TNK_Dependent_template_name) {
48331a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      AnnotateTemplateIdTokenAsType(SS);
4847f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
4857f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
4867f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      TypeTy *Type = Tok.getAnnotationValue();
4877f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      EndLocation = Tok.getAnnotationEndLoc();
4887f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor      ConsumeToken();
48931a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor
49031a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      if (Type)
49131a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor        return Type;
49231a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor      return true;
4937f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    }
4947f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
4957f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor    // Fall through to produce an error below.
4967f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  }
4977f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor
49842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  if (Tok.isNot(tok::identifier)) {
4991ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_class_name);
50031a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
50142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
50242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
50384d0a19828599e8623223632d59447fd498999cfDouglas Gregor  IdentifierInfo *Id = Tok.getIdentifierInfo();
50484d0a19828599e8623223632d59447fd498999cfDouglas Gregor  SourceLocation IdLoc = ConsumeToken();
50584d0a19828599e8623223632d59447fd498999cfDouglas Gregor
50684d0a19828599e8623223632d59447fd498999cfDouglas Gregor  if (Tok.is(tok::less)) {
50784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // It looks the user intended to write a template-id here, but the
50884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // template-name was wrong. Try to fix that.
50984d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateNameKind TNK = TNK_Type_template;
51084d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateTy Template;
51184d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, CurScope,
51284d0a19828599e8623223632d59447fd498999cfDouglas Gregor                                             SS, Template, TNK)) {
51384d0a19828599e8623223632d59447fd498999cfDouglas Gregor      Diag(IdLoc, diag::err_unknown_template_name)
51484d0a19828599e8623223632d59447fd498999cfDouglas Gregor        << Id;
51584d0a19828599e8623223632d59447fd498999cfDouglas Gregor    }
516193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
51784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (!Template)
51884d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
51984d0a19828599e8623223632d59447fd498999cfDouglas Gregor
520193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam    // Form the template name
52184d0a19828599e8623223632d59447fd498999cfDouglas Gregor    UnqualifiedId TemplateName;
52284d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TemplateName.setIdentifier(Id, IdLoc);
523193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
52484d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // Parse the full template-id, then turn it into a type.
52584d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateName,
52684d0a19828599e8623223632d59447fd498999cfDouglas Gregor                                SourceLocation(), true))
52784d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
52884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (TNK == TNK_Dependent_template_name)
52984d0a19828599e8623223632d59447fd498999cfDouglas Gregor      AnnotateTemplateIdTokenAsType(SS);
530193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
53184d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // If we didn't end up with a typename token, there's nothing more we
53284d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // can do.
53384d0a19828599e8623223632d59447fd498999cfDouglas Gregor    if (Tok.isNot(tok::annot_typename))
53484d0a19828599e8623223632d59447fd498999cfDouglas Gregor      return true;
535193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
53684d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // Retrieve the type from the annotation token, consume that token, and
53784d0a19828599e8623223632d59447fd498999cfDouglas Gregor    // return.
53884d0a19828599e8623223632d59447fd498999cfDouglas Gregor    EndLocation = Tok.getAnnotationEndLoc();
53984d0a19828599e8623223632d59447fd498999cfDouglas Gregor    TypeTy *Type = Tok.getAnnotationValue();
54084d0a19828599e8623223632d59447fd498999cfDouglas Gregor    ConsumeToken();
54184d0a19828599e8623223632d59447fd498999cfDouglas Gregor    return Type;
54284d0a19828599e8623223632d59447fd498999cfDouglas Gregor  }
54384d0a19828599e8623223632d59447fd498999cfDouglas Gregor
54442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // We have an identifier; check whether it is actually a type.
54584d0a19828599e8623223632d59447fd498999cfDouglas Gregor  TypeTy *Type = Actions.getTypeName(*Id, IdLoc, CurScope, SS, true);
546193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  if (!Type) {
547124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor    Diag(IdLoc, diag::err_expected_class_name);
54831a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor    return true;
54942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  }
55042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
55142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Consume the identifier.
55284d0a19828599e8623223632d59447fd498999cfDouglas Gregor  EndLocation = IdLoc;
55342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  return Type;
55442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor}
55542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
556e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
557e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
558e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that
559d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl/// cannot start a definition. If SuppressDeclarations is true, we do know.
560e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
561e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-specifier: [C++ class]
562e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}'
563e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-head '{' member-specification[opt] '}' attributes[opt]
564e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-head:
565e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key identifier[opt] base-clause[opt]
566e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier identifier base-clause[opt]
567e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         class-key nested-name-specifier[opt] simple-template-id
568e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          base-clause[opt]
569e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   class-key attributes[opt] identifier[opt] base-clause[opt]
5701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier
571e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          identifier base-clause[opt]
5721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU]   class-key attributes[opt] nested-name-specifier[opt]
573e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                          simple-template-id base-clause[opt]
574e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       class-key:
575e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'class'
576e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
577e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
578e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
579e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       elaborated-type-specifier: [C++ dcl.type.elab]
5801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] identifier
5811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///         class-key ::[opt] nested-name-specifier[opt] 'template'[opt]
5821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///                          simple-template-id
583e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
584e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  Note that the C++ class-specifier and elaborated-type-specifier,
585e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///  together, subsume the C99 struct-or-union-specifier:
586e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
587e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union-specifier: [C99 6.7.2.1]
588e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier[opt] '{' struct-contents '}'
589e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         struct-or-union identifier
590e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier[opt] '{' struct-contents
591e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                                                         '}' attributes[opt]
592e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU]   struct-or-union attributes[opt] identifier
593e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       struct-or-union:
594e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'struct'
595e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'union'
5964c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattnervoid Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
5974c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner                                 SourceLocation StartLoc, DeclSpec &DS,
5984d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                 const ParsedTemplateInfo &TemplateInfo,
599d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl                                 AccessSpecifier AS, bool SuppressDeclarations){
6004c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  DeclSpec::TST TagType;
6014c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  if (TagTokKind == tok::kw_struct)
6024c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_struct;
6034c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  else if (TagTokKind == tok::kw_class)
6044c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_class;
6054c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  else {
6064c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    assert(TagTokKind == tok::kw_union && "Not a class specifier");
6074c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner    TagType = DeclSpec::TST_union;
6084c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner  }
609e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
610374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  if (Tok.is(tok::code_completion)) {
611374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor    // Code completion for a struct, class, or union name.
612374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor    Actions.CodeCompleteTag(CurScope, TagType);
613dc8453422bec3bbf70c03920e01498d75783d122Douglas Gregor    ConsumeCodeCompletionToken();
614374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor  }
615193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
616bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  AttributeList *AttrList = 0;
617e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If attributes exist after tag, parse them.
618e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw___attribute))
619bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = ParseGNUAttributes();
620e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
621f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff  // If declspecs exist after tag, parse them.
622290eeb0ec2b6b91f3621e05ef541deb257fbea73Eli Friedman  if (Tok.is(tok::kw___declspec))
623bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = ParseMicrosoftDeclSpec(AttrList);
624193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
625bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // If C++0x attributes exist here, parse them.
626bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // FIXME: Are we consistent with the ordering of parsing of different
627bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // styles of attributes?
628bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (isCXX0XAttributeSpecifier())
629bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = addAttributeLists(AttrList, ParseCXX0XAttributes().AttrList);
6301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
631b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_pod)) {
632b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // GNU libstdc++ 4.2 uses __is_pod as the name of a struct template, but
633b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // __is_pod is a keyword in GCC >= 4.3. Therefore, when we see the
6341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // token sequence "struct __is_pod", make __is_pod into a normal
635b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // identifier rather than a keyword, to allow libstdc++ 4.2 to work
636b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // properly.
637b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.getIdentifierInfo()->setTokenID(tok::identifier);
638b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.setKind(tok::identifier);
639b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  }
640b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor
641b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_empty)) {
642b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // GNU libstdc++ 4.2 uses __is_empty as the name of a struct template, but
643b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // __is_empty is a keyword in GCC >= 4.3. Therefore, when we see the
6441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // token sequence "struct __is_empty", make __is_empty into a normal
645b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // identifier rather than a keyword, to allow libstdc++ 4.2 to work
646b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    // properly.
647b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.getIdentifierInfo()->setTokenID(tok::identifier);
648b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor    Tok.setKind(tok::identifier);
649b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor  }
6501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
651eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse the (optional) nested-name-specifier.
652aa87d33309f505b68c3bfc17486c93e4d224b24fJohn McCall  CXXScopeSpec &SS = DS.getTypeSpecScope();
65308d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  if (getLang().CPlusPlus) {
65408d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    // "FOO : BAR" is not a potential typo for "FOO::BAR".
65508d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner    ColonProtectionRAIIObject X(*this);
656193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
6579ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall    ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true);
6589ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall    if (SS.isSet())
65908d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner      if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
66008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner        Diag(Tok, diag::err_expected_ident);
66108d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner  }
662cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
6632cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor  TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
6642cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor
665cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor  // Parse the (optional) class name or simple-template-id.
666e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  IdentifierInfo *Name = 0;
667e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation NameLoc;
66839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  TemplateIdAnnotation *TemplateId = 0;
669e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::identifier)) {
670e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    Name = Tok.getIdentifierInfo();
671e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    NameLoc = ConsumeToken();
672193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
6735ee3734c0b5222a7c445591a1f14102c1b3a289bDouglas Gregor    if (Tok.is(tok::less) && getLang().CPlusPlus) {
674193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      // The name was supposed to refer to a template, but didn't.
6752cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // Eat the template argument list and try to continue parsing this as
6762cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      // a class (or template thereof).
6772cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      TemplateArgList TemplateArgs;
6782cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      SourceLocation LAngleLoc, RAngleLoc;
679193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, &SS,
6802cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor                                           true, LAngleLoc,
681314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor                                           TemplateArgs, RAngleLoc)) {
6822cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // We couldn't parse the template argument list at all, so don't
6832cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        // try to give any location information for the list.
6842cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        LAngleLoc = RAngleLoc = SourceLocation();
6852cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
686193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
6872cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      Diag(NameLoc, diag::err_explicit_spec_non_template)
688c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
6892cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << (TagType == DeclSpec::TST_class? 0
6902cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor            : TagType == DeclSpec::TST_struct? 1
6912cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor            : 2)
6922cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << Name
6932cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        << SourceRange(LAngleLoc, RAngleLoc);
694193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
695193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      // Strip off the last template parameter list if it was empty, since
696c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      // we've removed its template argument list.
697c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
698c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        if (TemplateParams && TemplateParams->size() > 1) {
699c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams->pop_back();
700c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        } else {
701c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          TemplateParams = 0;
702193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam          const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
703c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor            = ParsedTemplateInfo::NonTemplate;
704c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        }
705c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor      } else if (TemplateInfo.Kind
706c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor                                == ParsedTemplateInfo::ExplicitInstantiation) {
707c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        // Pretend this is just a forward declaration.
7082cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor        TemplateParams = 0;
709193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam        const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
7102cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor          = ParsedTemplateInfo::NonTemplate;
711193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam        const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc
712c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
713c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor        const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc
714c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor          = SourceLocation();
7152cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor      }
7162cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor    }
71739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  } else if (Tok.is(tok::annot_template_id)) {
71839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
71939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    NameLoc = ConsumeToken();
720cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor
721c45c232440dfafedca1a3773b904fb42609b1b19Douglas Gregor    if (TemplateId->Kind != TNK_Type_template) {
72239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // The template-name in the simple-template-id refers to
72339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // something other than a class template. Give an appropriate
72439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      // error message and skip to the ';'.
72539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SourceRange Range(NameLoc);
72639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      if (SS.isNotEmpty())
72739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        Range.setBegin(SS.getBeginLoc());
72839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
72939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
73039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor        << Name << static_cast<int>(TemplateId->Kind) << Range;
7311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
73239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      DS.SetTypeSpecError();
73339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      SkipUntil(tok::semi, false, true);
73439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      TemplateId->Destroy();
73539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      return;
736cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor    }
737e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
738e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
73967d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  // There are four options here.  If we have 'struct foo;', then this
74067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  // is either a forward declaration or a friend declaration, which
74167d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  // have to be treated differently.  If we have 'struct foo {...' or
74239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor  // 'struct foo :...' then this is a definition. Otherwise we have
743e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // something like 'struct foo xyz', a reference.
744d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // However, in some contexts, things look like declarations but are just
745d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // references, e.g.
746d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // new struct s;
747d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // or
748d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // &T::operator struct s;
749d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  // For these, SuppressDeclarations is true.
7500f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall  Action::TagUseKind TUK;
751d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  if (SuppressDeclarations)
752d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl    TUK = Action::TUK_Reference;
753d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl  else if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))){
754d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    if (DS.isFriendSpecified()) {
755d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // C++ [class.friend]p2:
756d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      //   A class shall not be defined in a friend declaration.
757d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      Diag(Tok.getLocation(), diag::err_friend_decl_defines_class)
758d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor        << SourceRange(DS.getFriendSpecLoc());
759d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor
760d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Skip everything up to the semicolon, so that this looks like a proper
761d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // friend class (or template thereof) declaration.
762d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      SkipUntil(tok::semi, true, true);
763d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      TUK = Action::TUK_Friend;
764d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    } else {
765d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      // Okay, this is a class definition.
766d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor      TUK = Action::TUK_Definition;
767d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor    }
768d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor  } else if (Tok.is(tok::semi))
76967d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    TUK = DS.isFriendSpecified() ? Action::TUK_Friend : Action::TUK_Declaration;
770e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  else
7710f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall    TUK = Action::TUK_Reference;
772e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
7730f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall  if (!Name && !TemplateId && TUK != Action::TUK_Definition) {
774e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // We have a declaration or reference to an anonymous class.
7751ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(StartLoc, diag::err_anon_type_definition)
7761ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner      << DeclSpec::getSpecifierName(TagType);
777e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
778e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SkipUntil(tok::comma, true);
77939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor
78039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    if (TemplateId)
78139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor      TemplateId->Destroy();
782e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    return;
783e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
784e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
785ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  // Create the tag portion of the class or class template.
786c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  Action::DeclResult TagOrTempResult = true; // invalid
787c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  Action::TypeResult TypeResult = true; // invalid
7884d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
789402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor  bool Owned = false;
790f1bbbb49f06a7462476cd88166fccda5feb15cabJohn McCall  if (TemplateId) {
7914d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // Explicit specialization, class template partial specialization,
7924d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    // or explicit instantiation.
7931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ASTTemplateArgsPtr TemplateArgsPtr(Actions,
79439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->getTemplateArgs(),
79539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                                       TemplateId->NumArgs);
7964d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
7970f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall        TUK == Action::TUK_Declaration) {
7984d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit instantiation of a class template.
7994d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
8001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        = Actions.ActOnExplicitInstantiation(CurScope,
80145f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                             TemplateInfo.ExternLoc,
8021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateInfo.TemplateLoc,
8034d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TagType,
8041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             StartLoc,
8054d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             SS,
8061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                     TemplateTy::make(TemplateId->Template),
8071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->TemplateNameLoc,
8081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->LAngleLoc,
8094d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateArgsPtr,
8101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             TemplateId->RAngleLoc,
811bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                             AttrList);
81274256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall
81374256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // Friend template-ids are treated as references unless
81474256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // they have template headers, in which case they're ill-formed
81574256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // (FIXME: "template <class T> friend class A<T>::B<int>;").
81674256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    // We diagnose this error in ActOnClassTemplateSpecialization.
81774256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    } else if (TUK == Action::TUK_Reference ||
81874256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall               (TUK == Action::TUK_Friend &&
81974256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall                TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
820c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall      TypeResult
8216b2becfc434b0bdced8560802c4d0e03148c61b8John McCall        = Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
8226b2becfc434b0bdced8560802c4d0e03148c61b8John McCall                                      TemplateId->TemplateNameLoc,
8236b2becfc434b0bdced8560802c4d0e03148c61b8John McCall                                      TemplateId->LAngleLoc,
8246b2becfc434b0bdced8560802c4d0e03148c61b8John McCall                                      TemplateArgsPtr,
8256b2becfc434b0bdced8560802c4d0e03148c61b8John McCall                                      TemplateId->RAngleLoc);
8266b2becfc434b0bdced8560802c4d0e03148c61b8John McCall
827c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall      TypeResult = Actions.ActOnTagTemplateIdType(TypeResult, TUK,
828c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall                                                  TagType, StartLoc);
8294d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    } else {
8304d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // This is an explicit specialization or a class template
8314d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // partial specialization.
8324d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TemplateParameterLists FakedParamLists;
8334d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
8344d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
8354d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // This looks like an explicit instantiation, because we have
8364d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // something like
8374d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
8384d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //   template class Foo<X>
8394d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        //
8403f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor        // but it actually has a definition. Most likely, this was
8414d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // meant to be an explicit specialization, but the user forgot
8424d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // the '<>' after 'template'.
8430f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall        assert(TUK == Action::TUK_Definition && "Expected a definition here");
8444d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
8451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        SourceLocation LAngleLoc
8464d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
8471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        Diag(TemplateId->TemplateNameLoc,
8484d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor             diag::err_explicit_instantiation_with_definition)
8494d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor          << SourceRange(TemplateInfo.TemplateLoc)
850849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor          << FixItHint::CreateInsertion(LAngleLoc, "<>");
8514d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
8524d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // Create a fake template parameter list that contains only
8534d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // "template<>", so that we treat this construct as a class
8544d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        // template specialization.
8554d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        FakedParamLists.push_back(
8561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          Actions.ActOnTemplateParameterList(0, SourceLocation(),
8574d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             TemplateInfo.TemplateLoc,
8581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             LAngleLoc,
8591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             0, 0,
8604d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                             LAngleLoc));
8614d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor        TemplateParams = &FakedParamLists;
8624d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      }
8634d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor
8644d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      // Build the class template specialization.
8654d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor      TagOrTempResult
8660f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall        = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TUK,
86739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       StartLoc, SS,
8681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateTy::make(TemplateId->Template),
8691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->TemplateNameLoc,
8701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->LAngleLoc,
87139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor                       TemplateArgsPtr,
8721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       TemplateId->RAngleLoc,
873bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                       AttrList,
8741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                       Action::MultiTemplateParamsArg(Actions,
875cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                    TemplateParams? &(*TemplateParams)[0] : 0,
876cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor                                 TemplateParams? TemplateParams->size() : 0));
8774d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor    }
87839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor    TemplateId->Destroy();
8793f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
8800f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall             TUK == Action::TUK_Declaration) {
8813f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Explicit instantiation of a member of a class template
8823f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // specialization, e.g.,
8833f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
8843f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //   template struct Outer<int>::Inner;
8853f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    //
8863f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    TagOrTempResult
8871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      = Actions.ActOnExplicitInstantiation(CurScope,
88845f965581935791a018df829a14dff53c1dd8f47Douglas Gregor                                           TemplateInfo.ExternLoc,
8891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TemplateInfo.TemplateLoc,
8901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                           TagType, StartLoc, SS, Name,
891bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                           NameLoc, AttrList);
8923f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  } else {
8933f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
8940f434ecbead44c1f4d5f9dda088f9827fa0dc40fJohn McCall        TUK == Action::TUK_Definition) {
8953f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor      // FIXME: Diagnose this particular error.
8963f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    }
8973f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor
898c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    bool IsDependent = false;
899c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
9003f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor    // Declaration or definition of a class type
9011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    TagOrTempResult = Actions.ActOnTag(CurScope, TagType, TUK, StartLoc, SS,
902bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                       Name, NameLoc, AttrList, AS,
9031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                  Action::MultiTemplateParamsArg(Actions,
9047cdbc5832084f45721693dfb1d93284c3e08efeeDouglas Gregor                                    TemplateParams? &(*TemplateParams)[0] : 0,
9057cdbc5832084f45721693dfb1d93284c3e08efeeDouglas Gregor                                    TemplateParams? TemplateParams->size() : 0),
906c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall                                       Owned, IsDependent);
907c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
908c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // If ActOnTag said the type was dependent, try again with the
909c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    // less common call.
910c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    if (IsDependent)
911c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall      TypeResult = Actions.ActOnDependentTag(CurScope, TagType, TUK,
912193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam                                             SS, Name, StartLoc, NameLoc);
9133f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor  }
914e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
915e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // If there is a body, parse it and inform the actions module.
916bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  if (TUK == Action::TUK_Definition) {
917bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    assert(Tok.is(tok::l_brace) ||
918bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall           (getLang().CPlusPlus && Tok.is(tok::colon)));
91907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    if (getLang().CPlusPlus)
920212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
92107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    else
922212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor      ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
923e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
924e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
925c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  void *Result;
926c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  if (!TypeResult.isInvalid()) {
927c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    TagType = DeclSpec::TST_typename;
928c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    Result = TypeResult.get();
929c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    Owned = false;
930c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else if (!TagOrTempResult.isInvalid()) {
931c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall    Result = TagOrTempResult.get().getAs<void>();
932c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall  } else {
933ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    DS.SetTypeSpecError();
93466e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson    return;
93566e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson  }
9361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
937fec54013fcd0eb72642741584ca04c1bc292bef8John McCall  const char *PrevSpec = 0;
938fec54013fcd0eb72642741584ca04c1bc292bef8John McCall  unsigned DiagID;
939c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall
940b988f9cde9bce0848d081b5cd1f6a48b86ec8108Douglas Gregor  // FIXME: The DeclSpec should keep the locations of both the keyword and the
941b988f9cde9bce0848d081b5cd1f6a48b86ec8108Douglas Gregor  // name (if there is one).
942b988f9cde9bce0848d081b5cd1f6a48b86ec8108Douglas Gregor  SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc;
943193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
944b988f9cde9bce0848d081b5cd1f6a48b86ec8108Douglas Gregor  if (DS.SetTypeSpecType(TagType, TSTLoc, PrevSpec, DiagID,
945c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall                         Result, Owned))
946fec54013fcd0eb72642741584ca04c1bc292bef8John McCall    Diag(StartLoc, DiagID) << PrevSpec;
947193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
9484ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // At this point, we've successfully parsed a class-specifier in 'definition'
9494ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // form (e.g. "struct foo { int x; }".  While we could just return here, we're
9504ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // going to look at what comes after it to improve error recovery.  If an
9514ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // impossible token occurs next, we assume that the programmer forgot a ; at
9524ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // the end of the declaration and recover that way.
9534ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  //
9544ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // This switch enumerates the valid "follow" set for definition.
9554ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  if (TUK == Action::TUK_Definition) {
956b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    bool ExpectedSemi = true;
9574ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    switch (Tok.getKind()) {
958b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    default: break;
9594ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    case tok::semi:               // struct foo {...} ;
96099c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::star:               // struct foo {...} *         P;
96199c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::amp:                // struct foo {...} &         R = ...
96299c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::identifier:         // struct foo {...} V         ;
96399c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::r_paren:            //(struct foo {...} )         {4}
96499c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_cxxscope:     // struct foo {...} a::       b;
96599c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_typename:     // struct foo {...} a         ::b;
96699c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::annot_template_id:  // struct foo {...} a<int>    ::b;
967c2e1c1af8ffe750b827284f207b9207112c7cc4eChris Lattner    case tok::l_paren:            // struct foo {...} (         x);
96816acfee729e00536af827935ccfcf69be721e462Chris Lattner    case tok::comma:              // __builtin_offsetof(struct foo{...} ,
969b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      ExpectedSemi = false;
970b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      break;
971b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    // Type qualifiers
972b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_const:           // struct foo {...} const     x;
973b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_volatile:        // struct foo {...} volatile  x;
974b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_restrict:        // struct foo {...} restrict  x;
975b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    case tok::kw_inline:          // struct foo {...} inline    foo() {};
97699c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    // Storage-class specifiers
97799c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_static:          // struct foo {...} static    x;
97899c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_extern:          // struct foo {...} extern    x;
97999c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_typedef:         // struct foo {...} typedef   x;
98099c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_register:        // struct foo {...} register  x;
98199c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner    case tok::kw_auto:            // struct foo {...} auto      x;
98233f992425213f381fc503699b26ee8cf9b60494eDouglas Gregor    case tok::kw_mutable:         // struct foo {...} mutable      x;
983b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // As shown above, type qualifiers and storage class specifiers absolutely
984b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // can occur after class specifiers according to the grammar.  However,
985b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // almost noone actually writes code like this.  If we see one of these,
986b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // it is much more likely that someone missed a semi colon and the
987b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // type/storage class specifier we're seeing is part of the *next*
988b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // intended declaration, as in:
989b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //
990b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //   struct foo { ... }
991b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //   typedef int X;
992b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      //
993b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // We'd really like to emit a missing semicolon error instead of emitting
994b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // an error on the 'int' saying that you can't have two type specifiers in
995b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // the same declaration of X.  Because of this, we look ahead past this
996b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // token to see if it's a type specifier.  If so, we know the code is
997b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      // otherwise invalid, so we can produce the expected semi error.
998b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      if (!isKnownToBeTypeSpecifier(NextToken()))
999b3a4e432c90be98c6d918087750397e86d030368Chris Lattner        ExpectedSemi = false;
10004ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      break;
1001193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1002193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam    case tok::r_brace:  // struct bar { struct foo {...} }
10034ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // Missing ';' at end of struct is accepted as an extension in C mode.
1004b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      if (!getLang().CPlusPlus)
1005b3a4e432c90be98c6d918087750397e86d030368Chris Lattner        ExpectedSemi = false;
1006b3a4e432c90be98c6d918087750397e86d030368Chris Lattner      break;
1007b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    }
1008193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1009b3a4e432c90be98c6d918087750397e86d030368Chris Lattner    if (ExpectedSemi) {
10104ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
10114ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner                       TagType == DeclSpec::TST_class ? "class"
10124ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner                       : TagType == DeclSpec::TST_struct? "struct" : "union");
10134ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // Push this token back into the preprocessor and change our current token
10144ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // to ';' so that the rest of the code recovers as though there were an
10154ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      // ';' after the definition.
10164ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner      PP.EnterToken(Tok);
1017193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam      Tok.setKind(tok::semi);
10184ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner    }
10194ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  }
1020e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1021e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
10221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived].
1023e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1024e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-clause : [C++ class.derived]
1025e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ':' base-specifier-list
1026e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier-list:
1027e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier '...'[opt]
1028e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         base-specifier-list ',' base-specifier '...'[opt]
1029b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattnervoid Parser::ParseBaseClause(DeclPtrTy ClassDecl) {
1030e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  assert(Tok.is(tok::colon) && "Not a base clause");
1031e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  ConsumeToken();
1032e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1033f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Build up an array of parsed base specifiers.
1034f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  llvm::SmallVector<BaseTy *, 8> BaseInfo;
1035f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
1036e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  while (true) {
1037e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Parse a base-specifier.
1038f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    BaseResult Result = ParseBaseSpecifier(ClassDecl);
10395ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor    if (Result.isInvalid()) {
1040e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Skip the rest of this base specifier, up until the comma or
1041e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // opening brace.
1042f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      SkipUntil(tok::comma, tok::l_brace, true, true);
1043f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor    } else {
1044f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor      // Add this to our array of base specifiers.
10455ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor      BaseInfo.push_back(Result.get());
1046e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
1047e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1048e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // If the next token is a comma, consume it and keep reading
1049e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // base-specifiers.
1050e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (Tok.isNot(tok::comma)) break;
10511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1052e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    // Consume the comma.
1053e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
1054e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1055f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor
1056f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor  // Attach the base specifiers
1057beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad  Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size());
1058e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1059e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1060e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is
1061e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example:
1062e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///    class foo : public bar, virtual private baz {
1063e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers.
1064e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1065e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       base-specifier: [C++ class.derived]
1066e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         ::[opt] nested-name-specifier[opt] class-name
1067e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt]
1068e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                        class-name
1069e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt]
1070e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///                        class-name
1071b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris LattnerParser::BaseResult Parser::ParseBaseSpecifier(DeclPtrTy ClassDecl) {
1072e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  bool IsVirtual = false;
1073e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation StartLoc = Tok.getLocation();
1074e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1075e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword.
1076e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
1077e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
1078e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
1079e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1080e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1081e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse an (optional) access specifier.
1082e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  AccessSpecifier Access = getAccessSpecifierIfPresent();
108392f883177b162928a8e632e4e3b93fafd2b26072John McCall  if (Access != AS_none)
1084e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    ConsumeToken();
10851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1086e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Parse the 'virtual' keyword (again!), in case it came after the
1087e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // access specifier.
1088e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  if (Tok.is(tok::kw_virtual))  {
1089e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    SourceLocation VirtualLoc = ConsumeToken();
1090e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    if (IsVirtual) {
1091e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor      // Complain about duplicate 'virtual'
10921ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner      Diag(VirtualLoc, diag::err_dup_virtual)
1093849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor        << FixItHint::CreateRemoval(VirtualLoc);
1094e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    }
1095e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1096e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor    IsVirtual = true;
1097e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1098e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1099eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  // Parse optional '::' and optional nested-name-specifier.
1100eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis  CXXScopeSpec SS;
1101193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0,
1102d2b43bf9116dad3d4ff3815590ef10f733d08289Douglas Gregor                                 /*EnteringContext=*/false);
1103e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1104e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // The location of the base class itself.
1105e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  SourceLocation BaseLoc = Tok.getLocation();
110642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor
110742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  // Parse the class-name.
11087f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceLocation EndLocation;
110931a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor  TypeResult BaseType = ParseClassName(EndLocation, &SS);
111031a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor  if (BaseType.isInvalid())
111142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor    return true;
11121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Find the complete source range for the base-specifier.
11147f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor  SourceRange Range(StartLoc, EndLocation);
11151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1116e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // Notify semantic analysis that we have parsed a complete
1117e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  // base-specifier.
1118a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl  return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
111931a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor                                    BaseType.get(), BaseLoc);
1120e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
1121e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor
1122e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is
1123e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier.
1124e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///
1125e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///       access-specifier: [C++ class.derived]
1126e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'private'
1127e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'protected'
1128e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor///         'public'
11291eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAccessSpecifier Parser::getAccessSpecifierIfPresent() const {
1130e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  switch (Tok.getKind()) {
1131e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  default: return AS_none;
1132e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_private: return AS_private;
1133e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_protected: return AS_protected;
1134e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  case tok::kw_public: return AS_public;
1135e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor  }
1136e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor}
11374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1138d33133cdc1af466f9c276249b2621be03867888bEli Friedmanvoid Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
1139d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                             DeclPtrTy ThisDecl) {
1140d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // We just declared a member function. If this member function
1141d33133cdc1af466f9c276249b2621be03867888bEli Friedman  // has any default arguments, we'll need to parse them later.
1142d33133cdc1af466f9c276249b2621be03867888bEli Friedman  LateParsedMethodDeclaration *LateMethod = 0;
11431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  DeclaratorChunk::FunctionTypeInfo &FTI
1144d33133cdc1af466f9c276249b2621be03867888bEli Friedman    = DeclaratorInfo.getTypeObject(0).Fun;
1145d33133cdc1af466f9c276249b2621be03867888bEli Friedman  for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
1146d33133cdc1af466f9c276249b2621be03867888bEli Friedman    if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
1147d33133cdc1af466f9c276249b2621be03867888bEli Friedman      if (!LateMethod) {
1148d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Push this method onto the stack of late-parsed method
1149d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // declarations.
1150d33133cdc1af466f9c276249b2621be03867888bEli Friedman        getCurrentClass().MethodDecls.push_back(
1151d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                LateParsedMethodDeclaration(ThisDecl));
1152d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateMethod = &getCurrentClass().MethodDecls.back();
1153d83d04041f64a2c89123d227fa8003b482391279Douglas Gregor        LateMethod->TemplateScope = CurScope->isTemplateParamScope();
1154d33133cdc1af466f9c276249b2621be03867888bEli Friedman
1155d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // Add all of the parameters prior to this one (they don't
1156d33133cdc1af466f9c276249b2621be03867888bEli Friedman        // have default arguments).
1157d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateMethod->DefaultArgs.reserve(FTI.NumArgs);
1158d33133cdc1af466f9c276249b2621be03867888bEli Friedman        for (unsigned I = 0; I < ParamIdx; ++I)
1159d33133cdc1af466f9c276249b2621be03867888bEli Friedman          LateMethod->DefaultArgs.push_back(
11608f8210c47797f013e0fb24a26f9c4751b10783feDouglas Gregor                             LateParsedDefaultArgument(FTI.ArgInfo[I].Param));
1161d33133cdc1af466f9c276249b2621be03867888bEli Friedman      }
1162d33133cdc1af466f9c276249b2621be03867888bEli Friedman
1163d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // Add this parameter to the list of parameters (it or may
1164d33133cdc1af466f9c276249b2621be03867888bEli Friedman      // not have a default argument).
1165d33133cdc1af466f9c276249b2621be03867888bEli Friedman      LateMethod->DefaultArgs.push_back(
1166d33133cdc1af466f9c276249b2621be03867888bEli Friedman        LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
1167d33133cdc1af466f9c276249b2621be03867888bEli Friedman                                  FTI.ArgInfo[ParamIdx].DefaultArgTokens));
1168d33133cdc1af466f9c276249b2621be03867888bEli Friedman    }
1169d33133cdc1af466f9c276249b2621be03867888bEli Friedman  }
1170d33133cdc1af466f9c276249b2621be03867888bEli Friedman}
1171d33133cdc1af466f9c276249b2621be03867888bEli Friedman
11724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
11734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
11744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declaration:
11754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         decl-specifier-seq[opt] member-declarator-list[opt] ';'
11764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         function-definition ';'[opt]
11774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
11784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         using-declaration                                            [TODO]
1179511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration
11805aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson///         template-declaration
1181bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU]   '__extension__' member-declaration
11824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
11834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator-list:
11844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator
11854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declarator-list ',' member-declarator
11864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
11874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-declarator:
11884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         declarator pure-specifier[opt]
11894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         declarator constant-initializer[opt]
11904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         identifier[opt] ':' constant-expression
11914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
1192e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl///       pure-specifier:
11934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '= 0'
11944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
11954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       constant-initializer:
11964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         '=' constant-expression
11974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
119837b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregorvoid Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
119937b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor                                       const ParsedTemplateInfo &TemplateInfo) {
120060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  // Access declarations.
120160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  if (!TemplateInfo.Kind &&
120260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) &&
12039ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall      !TryAnnotateCXXScopeToken() &&
120460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      Tok.is(tok::annot_cxxscope)) {
120560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    bool isAccessDecl = false;
120660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    if (NextToken().is(tok::identifier))
120760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      isAccessDecl = GetLookAheadToken(2).is(tok::semi);
120860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    else
120960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      isAccessDecl = NextToken().is(tok::kw_operator);
121060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
121160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    if (isAccessDecl) {
121260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // Collect the scope specifier token we annotated earlier.
121360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      CXXScopeSpec SS;
121460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      ParseOptionalCXXScopeSpecifier(SS, /*ObjectType*/ 0, false);
121560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
121660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // Try to parse an unqualified-id.
121760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      UnqualifiedId Name;
121860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      if (ParseUnqualifiedId(SS, false, true, true, /*ObjectType*/ 0, Name)) {
121960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        SkipUntil(tok::semi);
122060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        return;
122160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      }
122260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
122360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      // TODO: recover from mistakenly-qualified operator declarations.
122460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      if (ExpectAndConsume(tok::semi,
122560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           diag::err_expected_semi_after,
122660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           "access declaration",
122760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                           tok::semi))
122860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall        return;
122960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
123060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      Actions.ActOnUsingDeclaration(CurScope, AS,
123160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    false, SourceLocation(),
123260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    SS, Name,
123360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    /* AttrList */ 0,
123460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    /* IsTypeName */ false,
123560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall                                    SourceLocation());
123660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall      return;
123760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall    }
123860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall  }
123960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall
1240511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson  // static_assert-declaration
1241682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  if (Tok.is(tok::kw_static_assert)) {
124237b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    // FIXME: Check for templates
124397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
124497144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    ParseStaticAssertDeclaration(DeclEnd);
1245682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1246682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
12471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1248682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  if (Tok.is(tok::kw_template)) {
12491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert(!TemplateInfo.TemplateParams &&
125037b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor           "Nested template improperly parsed?");
125197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner    SourceLocation DeclEnd;
12521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd,
12534d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor                                         AS);
1254682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
1255682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  }
12565aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson
1257bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  // Handle:  member-declaration ::= '__extension__' member-declaration
1258bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  if (Tok.is(tok::kw___extension__)) {
1259bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    // __extension__ silences extension warnings in the subexpression.
1260bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ExtensionRAIIObject O(Diags);  // Use RAII to do this.
1261bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner    ConsumeToken();
126237b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    return ParseCXXClassMemberDeclaration(AS, TemplateInfo);
1263bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner  }
12649cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
12654ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it
12664ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner  // is a bitfield.
1267a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner  ColonProtectionRAIIObject X(*this);
1268193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1269bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  CXX0XAttributeList AttrList;
1270bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  // Optional C++0x attribute-specifier
1271a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner  if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
1272bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    AttrList = ParseCXX0XAttributes();
1273bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
12749cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  if (Tok.is(tok::kw_using)) {
127537b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    // FIXME: Check for template aliases
1276193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1277bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (AttrList.HasAttr)
1278bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      Diag(AttrList.Range.getBegin(), diag::err_attributes_not_allowed)
1279bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        << AttrList.Range;
12801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12819cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    // Eat 'using'.
12829cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    SourceLocation UsingLoc = ConsumeToken();
12839cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
12849cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    if (Tok.is(tok::kw_namespace)) {
12859cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      Diag(UsingLoc, diag::err_using_namespace_in_class);
12869cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SkipUntil(tok::semi, true, true);
1287ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    } else {
12889cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      SourceLocation DeclEnd;
12899cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor      // Otherwise, it must be using-declaration.
1290595adc1795cc2c079ef5876100e01acd10a0504aAnders Carlsson      ParseUsingDeclaration(Declarator::MemberContext, UsingLoc, DeclEnd, AS);
12919cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    }
12929cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor    return;
12939cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor  }
12949cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor
12954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  SourceLocation DSStart = Tok.getLocation();
12964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // decl-specifier-seq:
12974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Parse the common declaration-specifiers piece.
129854abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclSpec DS(*this);
1299bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  DS.AddAttributes(AttrList.AttrList);
130037b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor  ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class);
13014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1302dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall  Action::MultiTemplateParamsArg TemplateParams(Actions,
1303dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
1304dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
1305dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall
13064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::semi)) {
13074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
1308aec0371e62be013a2e6466688ccf6a7460880262John McCall    Actions.ParsedFreeStandingDeclSpec(CurScope, AS, DS);
130967d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    return;
13104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
131107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis
131254abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall  ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext);
13134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13143a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis  if (Tok.isNot(tok::colon)) {
1315a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner    // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
1316a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner    ColonProtectionRAIIObject X(*this);
1317a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner
13183a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Parse the first declarator.
13193a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    ParseDeclarator(DeclaratorInfo);
13203a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // Error parsing the declarator?
132110bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor    if (!DeclaratorInfo.hasName()) {
13223a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      // If so, skip until the semi-colon or a }.
13234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      SkipUntil(tok::r_brace, true);
13243a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (Tok.is(tok::semi))
13253a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeToken();
1326682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
13274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
13284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13291b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson    // If attributes exist after the declarator, but before an '{', parse them.
13301b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson    if (Tok.is(tok::kw___attribute)) {
13311b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson      SourceLocation Loc;
13321b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson      AttributeList *AttrList = ParseGNUAttributes(&Loc);
13331b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson      DeclaratorInfo.AddAttributes(AttrList, Loc);
13341b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson    }
13351b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson
13363a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    // function-definition:
13377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    if (Tok.is(tok::l_brace)
1338d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl        || (DeclaratorInfo.isFunctionDeclarator() &&
1339d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl            (Tok.is(tok::colon) || Tok.is(tok::kw_try)))) {
13403a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (!DeclaratorInfo.isFunctionDeclarator()) {
13413a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        Diag(Tok, diag::err_func_def_no_params);
13423a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
13433a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        SkipUntil(tok::r_brace, true);
1344682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
13453a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
13463a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis
13473a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
13483a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        Diag(Tok, diag::err_function_declared_typedef);
13493a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // This recovery skips the entire function body. It would be nice
13503a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // to simply call ParseCXXInlineMethodDef() below, however Sema
13513a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        // assumes the declarator represents a function, not a typedef.
13523a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        ConsumeBrace();
13533a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis        SkipUntil(tok::r_brace, true);
1354682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner        return;
13553a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      }
13564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
135737b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor      ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo);
1358682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      return;
13593a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    }
13604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
13614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // member-declarator-list:
13634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator
13644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //   member-declarator-list ',' member-declarator
13654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1366682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner  llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup;
136715faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl  OwningExprResult BitfieldSize(Actions);
136815faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl  OwningExprResult Init(Actions);
1369e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl  bool Deleted = false;
13704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
13714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  while (1) {
13724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // member-declarator:
13734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   declarator pure-specifier[opt]
13744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   declarator constant-initializer[opt]
13754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   identifier[opt] ':' constant-expression
13764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::colon)) {
13774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
13780e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      BitfieldSize = ParseConstantExpression();
13790e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl      if (BitfieldSize.isInvalid())
13804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        SkipUntil(tok::comma, true, true);
13814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
13821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // pure-specifier:
13844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   '= 0'
13854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //
13864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // constant-initializer:
13874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    //   '=' constant-expression
1388e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //
1389e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    // defaulted/deleted function-definition:
1390e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //   '=' 'default'                          [TODO]
1391e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    //   '=' 'delete'
13924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::equal)) {
13934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
1394e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl      if (getLang().CPlusPlus0x && Tok.is(tok::kw_delete)) {
1395e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        ConsumeToken();
1396e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        Deleted = true;
1397e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl      } else {
1398e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        Init = ParseInitializer();
1399e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl        if (Init.isInvalid())
1400e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl          SkipUntil(tok::comma, true, true);
1401e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl      }
14024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
14034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1404e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    // If a simple-asm-expr is present, parse it.
1405e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    if (Tok.is(tok::kw_asm)) {
1406e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      SourceLocation Loc;
1407e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
1408e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      if (AsmLabel.isInvalid())
1409e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner        SkipUntil(tok::comma, true, true);
1410e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner
1411e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      DeclaratorInfo.setAsmLabel(AsmLabel.release());
1412e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner      DeclaratorInfo.SetRangeEnd(Loc);
1413e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner    }
1414e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner
14154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If attributes exist after the declarator, parse them.
1416ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    if (Tok.is(tok::kw___attribute)) {
1417ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      SourceLocation Loc;
1418bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttributeList *AttrList = ParseGNUAttributes(&Loc);
1419ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      DeclaratorInfo.AddAttributes(AttrList, Loc);
1420ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    }
14214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
142207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // NOTE: If Sema is the Action module and declarator is an instance field,
1423682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    // this call will *not* return the created decl; It will return null.
142407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis    // See Sema::ActOnCXXMemberDeclarator for details.
142567d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall
142667d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    DeclPtrTy ThisDecl;
142767d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall    if (DS.isFriendSpecified()) {
1428bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall      // TODO: handle initializers, bitfields, 'delete'
1429bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall      ThisDecl = Actions.ActOnFriendFunctionDecl(CurScope, DeclaratorInfo,
1430bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall                                                 /*IsDefinition*/ false,
1431bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall                                                 move(TemplateParams));
143237b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    } else {
143367d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall      ThisDecl = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
143467d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  DeclaratorInfo,
143537b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor                                                  move(TemplateParams),
143667d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  BitfieldSize.release(),
143767d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  Init.release(),
1438d1a7846699a82f85ff3ce6b2e383409537c3f5c5Sebastian Redl                                                  /*IsDefinition*/Deleted,
143967d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall                                                  Deleted);
144037b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    }
1441682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    if (ThisDecl)
1442682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner      DeclsInGroup.push_back(ThisDecl);
14434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
144472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    if (DeclaratorInfo.isFunctionDeclarator() &&
14451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        DeclaratorInfo.getDeclSpec().getStorageClassSpec()
144672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor          != DeclSpec::SCS_typedef) {
1447d33133cdc1af466f9c276249b2621be03867888bEli Friedman      HandleMemberFunctionDefaultArgs(DeclaratorInfo, ThisDecl);
144872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    }
144972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor
145054abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall    DeclaratorInfo.complete(ThisDecl);
145154abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall
14524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If we don't have a comma, it is either the end of the list (a ';')
14534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // or an error, bail out.
14544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.isNot(tok::comma))
14554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
14561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Consume the comma.
14584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ConsumeToken();
14591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Parse the next declarator.
14614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    DeclaratorInfo.clear();
146215faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl    BitfieldSize = 0;
146315faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl    Init = 0;
1464e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl    Deleted = false;
14651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Attributes are only allowed on the second declarator.
1467ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    if (Tok.is(tok::kw___attribute)) {
1468ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      SourceLocation Loc;
1469bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttributeList *AttrList = ParseGNUAttributes(&Loc);
1470ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl      DeclaratorInfo.AddAttributes(AttrList, Loc);
1471ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    }
14724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
14733a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis    if (Tok.isNot(tok::colon))
14743a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis      ParseDeclarator(DeclaratorInfo);
14754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
14764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1477ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner  if (ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
1478ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    // Skip to end of block or statement.
1479ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    SkipUntil(tok::r_brace, true, true);
1480ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    // If we stopped at a ';', eat it.
1481ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner    if (Tok.is(tok::semi)) ConsumeToken();
1482682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner    return;
14834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
14844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1485ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner  Actions.FinalizeDeclaratorGroup(CurScope, DS, DeclsInGroup.data(),
1486ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner                                  DeclsInGroup.size());
14874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
14884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
14894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition.
14904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
14914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///       member-specification:
14924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         member-declaration member-specification[opt]
14934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///         access-specifier ':' member-specification[opt]
14944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis///
14954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidisvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
1496b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner                                         unsigned TagType, DeclPtrTy TagDecl) {
149731fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta  assert((TagType == DeclSpec::TST_struct ||
14984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis         TagType == DeclSpec::TST_union  ||
149931fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta         TagType == DeclSpec::TST_class) && "Invalid TagType!");
15004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
150149f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner  PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions,
150249f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner                                        PP.getSourceManager(),
150349f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner                                        "parsing struct/union/class body");
15041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
150526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  // Determine whether this is a non-nested class. Note that local
150626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  // classes are *not* considered to be nested classes.
150726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  bool NonNestedClass = true;
150826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  if (!ClassStack.empty()) {
150926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor    for (const Scope *S = CurScope; S; S = S->getParent()) {
151026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      if (S->isClassScope()) {
151126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // We're inside a class scope, so this is a nested class.
151226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        NonNestedClass = false;
151326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        break;
151426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      }
151526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor
151626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      if ((S->getFlags() & Scope::FnScope)) {
151726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // If we're in a function or function template declared in the
151826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // body of a class, then this is a local class rather than a
151926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        // nested class.
152026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        const Scope *Parent = S->getParent();
152126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        if (Parent->isTemplateParamScope())
152226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor          Parent = Parent->getParent();
152326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor        if (Parent->isClassScope())
152426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor          break;
152526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor      }
152626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor    }
152726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  }
15284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
15294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Enter a scope for the class.
15303218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope);
15314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
15326569d68745c8213709740337d2be52b031384f58Douglas Gregor  // Note that we are parsing a new (potentially-nested) class definition.
153326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass);
15346569d68745c8213709740337d2be52b031384f58Douglas Gregor
1535ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor  if (TagDecl)
1536ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor    Actions.ActOnTagStartDefinition(CurScope, TagDecl);
1537bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
1538bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  if (Tok.is(tok::colon)) {
1539bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    ParseBaseClause(TagDecl);
1540bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
1541bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    if (!Tok.is(tok::l_brace)) {
1542bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall      Diag(Tok, diag::err_expected_lbrace_after_base_specifiers);
1543db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall
1544db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall      if (TagDecl)
1545db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall        Actions.ActOnTagDefinitionError(CurScope, TagDecl);
1546bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall      return;
1547bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall    }
1548bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  }
1549bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
1550bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  assert(Tok.is(tok::l_brace));
1551bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
1552bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall  SourceLocation LBraceLoc = ConsumeBrace();
1553bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall
155442a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
155542a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall    Actions.ActOnStartCXXMemberDeclarations(CurScope, TagDecl, LBraceLoc);
1556f9368159334ff86ea5fa367225c1a580977f3b03John McCall
15574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // C++ 11p3: Members of a class defined with the keyword class are private
15584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // by default. Members of a class defined with the keywords struct or union
15594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // are public by default.
15604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  AccessSpecifier CurAS;
15614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (TagType == DeclSpec::TST_class)
15624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_private;
15634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  else
15644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    CurAS = AS_public;
15654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
15664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // While we still have something to read, read the member-declarations.
15674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
15684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Each iteration of this loop reads one member-declaration.
15691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Check for extraneous top-level semicolon.
15714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (Tok.is(tok::semi)) {
1572c2253f5ca170984fcd4f30f8823148e8cb71336bChris Lattner      Diag(Tok, diag::ext_extra_struct_semi)
1573849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor        << FixItHint::CreateRemoval(Tok.getLocation());
15744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
15754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      continue;
15764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
15774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
15784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    AccessSpecifier AS = getAccessSpecifierIfPresent();
15794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    if (AS != AS_none) {
15804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      // Current token is a C++ access specifier.
15814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      CurAS = AS;
15826206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara      SourceLocation ASLoc = Tok.getLocation();
15836206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara      ConsumeToken();
15846206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara      if (Tok.is(tok::colon))
15856206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara        Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
15866206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara      else
15876206d53f67613958ae1b023aba337ebb46f11a8bAbramo Bagnara        Diag(Tok, diag::err_expected_colon);
15884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
15894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      continue;
15904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
15914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
159237b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor    // FIXME: Make sure we don't have a template here.
15931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Parse all the comma separated declarators.
15954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    ParseCXXClassMemberDeclaration(CurAS);
15964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
15971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
15991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // If attributes exist after class contents, parse them.
16011e37765c9257ef1d051f54a674eaa964bdba9693Ted Kremenek  llvm::OwningPtr<AttributeList> AttrList;
16024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  if (Tok.is(tok::kw___attribute))
16030b4c9b5834a0a5520d2cd32227a53cf7f73fedcaDouglas Gregor    AttrList.reset(ParseGNUAttributes());
16044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
160542a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
160642a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall    Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl,
160742a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall                                              LBraceLoc, RBraceLoc,
160842a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall                                              AttrList.get());
16094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
16104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // C++ 9.2p2: Within the class member-specification, the class is regarded as
16114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // complete within function bodies, default arguments,
16124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // exception-specifications, and constructor ctor-initializers (including
16134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // such things in nested classes).
16144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  //
161572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor  // FIXME: Only function bodies and constructor ctor-initializers are
161672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor  // parsed correctly, fix the rest.
161726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  if (NonNestedClass) {
16184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // We are not inside a nested class. This class and its nested classes
161972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    // are complete and we can parse the delayed portions of method
162072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    // declarations and the lexed inline method definitions.
16216569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDeclarations(getCurrentClass());
16226569d68745c8213709740337d2be52b031384f58Douglas Gregor    ParseLexedMethodDefs(getCurrentClass());
16234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
16244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
162542a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall  if (TagDecl)
162642a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall    Actions.ActOnTagFinishDefinition(CurScope, TagDecl, RBraceLoc);
1627db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall
16284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Leave the class scope.
16296569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingDef.Pop();
16308935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor  ClassScope.Exit();
16314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
16327ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
16337ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer,
16347ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a
16357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers
16367ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below:
16377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
16387ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code
16397ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { };
16407ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base {
16417ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   int x;
16427ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   float f;
16437ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public:
16447ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///   Derived(float f) : Base(), x(17), f(f) { }
16457ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// };
16467ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode
16477ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
16481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  ctor-initializer:
16491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///          ':' mem-initializer-list
16507ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
16511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++]  mem-initializer-list:
16521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///          mem-initializer
16531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///          mem-initializer , mem-initializer-list
1654b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattnervoid Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) {
16557ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'");
16567ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
16577ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation ColonLoc = ConsumeToken();
16581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16597ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  llvm::SmallVector<MemInitTy*, 4> MemInitializers;
16609db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor  bool AnyErrors = false;
1661193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
16627ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  do {
16637ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
16645ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor    if (!MemInit.isInvalid())
16655ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor      MemInitializers.push_back(MemInit.get());
16669db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor    else
16679db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor      AnyErrors = true;
1668193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
16697ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    if (Tok.is(tok::comma))
16707ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      ConsumeToken();
16717ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    else if (Tok.is(tok::l_brace))
16727ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
16737ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    else {
16747ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      // Skip over garbage, until we get to '{'.  Don't eat the '{'.
1675d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl      Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
16767ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      SkipUntil(tok::l_brace, true, true);
16777ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor      break;
16787ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    }
16797ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  } while (true);
16807ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
16811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc,
16829db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                               MemInitializers.data(), MemInitializers.size(),
16839db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor                               AnyErrors);
16847ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
16857ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
16867ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is
16877ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one
16887ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See
16897ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example.
16907ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///
16917ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer:
16927ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         mem-initializer-id '(' expression-list[opt] ')'
16931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
16947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id:
16957ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         '::'[opt] nested-name-specifier[opt] class-name
16967ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor///         identifier
1697b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris LattnerParser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
1698bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  // parse '::'[opt] nested-name-specifier[opt]
1699bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian  CXXScopeSpec SS;
17002dd078ae50ff7be1fb25ebeedde45e9ab691a4f0Douglas Gregor  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
1701961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  TypeTy *TemplateTypeTy = 0;
1702961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (Tok.is(tok::annot_template_id)) {
1703961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    TemplateIdAnnotation *TemplateId
1704961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
1705d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor    if (TemplateId->Kind == TNK_Type_template ||
1706d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor        TemplateId->Kind == TNK_Dependent_template_name) {
1707961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      AnnotateTemplateIdTokenAsType(&SS);
1708961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
1709961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian      TemplateTypeTy = Tok.getAnnotationValue();
1710961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian    }
1711961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  }
1712961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  if (!TemplateTypeTy && Tok.isNot(tok::identifier)) {
17131ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_member_or_base_name);
17147ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
17157ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
17161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17177ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Get the identifier. This may be a member name or a class name,
17187ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // but we'll let the semantic analysis determine which it is.
1719961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  IdentifierInfo *II = Tok.is(tok::identifier) ? Tok.getIdentifierInfo() : 0;
17207ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation IdLoc = ConsumeToken();
17217ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
17227ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Parse the '('.
17237ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  if (Tok.isNot(tok::l_paren)) {
17241ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner    Diag(Tok, diag::err_expected_lparen);
17257ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
17267ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
17277ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation LParenLoc = ConsumeParen();
17287ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
17297ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  // Parse the optional expression-list.
1730a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl  ExprVector ArgExprs(Actions);
17317ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  CommaLocsTy CommaLocs;
17327ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
17337ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    SkipUntil(tok::r_paren);
17347ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor    return true;
17357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
17367ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
17377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
17387ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor
1739961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian  return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, SS, II,
1740961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian                                     TemplateTypeTy, IdLoc,
1741a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl                                     LParenLoc, ArgExprs.take(),
1742beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad                                     ArgExprs.size(), CommaLocs.data(),
1743beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad                                     RParenLoc);
17447ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor}
17450fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
17460fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// ParseExceptionSpecification - Parse a C++ exception-specification
17470fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// (C++ [except.spec]).
17480fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
1749a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       exception-specification:
1750a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         'throw' '(' type-id-list [opt] ')'
1751a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS]    'throw' '(' '...' ')'
17521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump///
1753a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///       type-id-list:
1754a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         type-id
1755a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor///         type-id-list ',' type-id
17560fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor///
17577dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redlbool Parser::ParseExceptionSpecification(SourceLocation &EndLoc,
1758ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl                                         llvm::SmallVector<TypeTy*, 2>
1759ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl                                             &Exceptions,
1760ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl                                         llvm::SmallVector<SourceRange, 2>
1761ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl                                             &Ranges,
17627dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl                                         bool &hasAnyExceptionSpec) {
17630fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  assert(Tok.is(tok::kw_throw) && "expected throw");
17641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17650fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  SourceLocation ThrowLoc = ConsumeToken();
17661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17670fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  if (!Tok.is(tok::l_paren)) {
17680fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor    return Diag(Tok, diag::err_expected_lparen_after) << "throw";
17690fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
17700fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  SourceLocation LParenLoc = ConsumeParen();
17710fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
1772a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // Parse throw(...), a Microsoft extension that means "this function
1773a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  // can throw anything".
1774a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  if (Tok.is(tok::ellipsis)) {
17757dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl    hasAnyExceptionSpec = true;
1776a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    SourceLocation EllipsisLoc = ConsumeToken();
1777a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    if (!getLang().Microsoft)
1778a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor      Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
1779ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl    EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
1780a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor    return false;
1781a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor  }
1782a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor
17830fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  // Parse the sequence of type-ids.
1784ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl  SourceRange Range;
17850fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  while (Tok.isNot(tok::r_paren)) {
1786ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    TypeResult Res(ParseTypeName(&Range));
1787ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    if (!Res.isInvalid()) {
17887dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl      Exceptions.push_back(Res.get());
1789ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl      Ranges.push_back(Range);
1790ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl    }
17910fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor    if (Tok.is(tok::comma))
17920fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      ConsumeToken();
17937dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl    else
17940fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor      break;
17950fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  }
17960fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor
1797ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl  EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
17980fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor  return false;
17990fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor}
18006569d68745c8213709740337d2be52b031384f58Douglas Gregor
18016569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief We have just started parsing the definition of a new class,
18026569d68745c8213709740337d2be52b031384f58Douglas Gregor/// so push that class onto our stack of classes that is currently
18036569d68745c8213709740337d2be52b031384f58Douglas Gregor/// being parsed.
180426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregorvoid Parser::PushParsingClass(DeclPtrTy ClassDecl, bool NonNestedClass) {
180526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  assert((NonNestedClass || !ClassStack.empty()) &&
18066569d68745c8213709740337d2be52b031384f58Douglas Gregor         "Nested class without outer class");
180726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor  ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass));
18086569d68745c8213709740337d2be52b031384f58Douglas Gregor}
18096569d68745c8213709740337d2be52b031384f58Douglas Gregor
18106569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Deallocate the given parsed class and all of its nested
18116569d68745c8213709740337d2be52b031384f58Douglas Gregor/// classes.
18126569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
18136569d68745c8213709740337d2be52b031384f58Douglas Gregor  for (unsigned I = 0, N = Class->NestedClasses.size(); I != N; ++I)
18146569d68745c8213709740337d2be52b031384f58Douglas Gregor    DeallocateParsedClasses(Class->NestedClasses[I]);
18156569d68745c8213709740337d2be52b031384f58Douglas Gregor  delete Class;
18166569d68745c8213709740337d2be52b031384f58Douglas Gregor}
18176569d68745c8213709740337d2be52b031384f58Douglas Gregor
18186569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Pop the top class of the stack of classes that are
18196569d68745c8213709740337d2be52b031384f58Douglas Gregor/// currently being parsed.
18206569d68745c8213709740337d2be52b031384f58Douglas Gregor///
18216569d68745c8213709740337d2be52b031384f58Douglas Gregor/// This routine should be called when we have finished parsing the
18226569d68745c8213709740337d2be52b031384f58Douglas Gregor/// definition of a class, but have not yet popped the Scope
18236569d68745c8213709740337d2be52b031384f58Douglas Gregor/// associated with the class's definition.
18246569d68745c8213709740337d2be52b031384f58Douglas Gregor///
18256569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \returns true if the class we've popped is a top-level class,
18266569d68745c8213709740337d2be52b031384f58Douglas Gregor/// false otherwise.
18276569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::PopParsingClass() {
18286569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");
18291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18306569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParsingClass *Victim = ClassStack.top();
18316569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.pop();
18326569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (Victim->TopLevelClass) {
18336569d68745c8213709740337d2be52b031384f58Douglas Gregor    // Deallocate all of the nested classes of this class,
18346569d68745c8213709740337d2be52b031384f58Douglas Gregor    // recursively: we don't need to keep any of this information.
18356569d68745c8213709740337d2be52b031384f58Douglas Gregor    DeallocateParsedClasses(Victim);
18366569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
18371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
18386569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(!ClassStack.empty() && "Missing top-level class?");
18396569d68745c8213709740337d2be52b031384f58Douglas Gregor
18406569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (Victim->MethodDecls.empty() && Victim->MethodDefs.empty() &&
18416569d68745c8213709740337d2be52b031384f58Douglas Gregor      Victim->NestedClasses.empty()) {
18426569d68745c8213709740337d2be52b031384f58Douglas Gregor    // The victim is a nested class, but we will not need to perform
18436569d68745c8213709740337d2be52b031384f58Douglas Gregor    // any processing after the definition of this class since it has
18446569d68745c8213709740337d2be52b031384f58Douglas Gregor    // no members whose handling was delayed. Therefore, we can just
18456569d68745c8213709740337d2be52b031384f58Douglas Gregor    // remove this nested class.
18466569d68745c8213709740337d2be52b031384f58Douglas Gregor    delete Victim;
18476569d68745c8213709740337d2be52b031384f58Douglas Gregor    return;
18486569d68745c8213709740337d2be52b031384f58Douglas Gregor  }
18496569d68745c8213709740337d2be52b031384f58Douglas Gregor
18506569d68745c8213709740337d2be52b031384f58Douglas Gregor  // This nested class has some members that will need to be processed
18516569d68745c8213709740337d2be52b031384f58Douglas Gregor  // after the top-level class is completely defined. Therefore, add
18526569d68745c8213709740337d2be52b031384f58Douglas Gregor  // it to the list of nested classes within its parent.
18536569d68745c8213709740337d2be52b031384f58Douglas Gregor  assert(CurScope->isClassScope() && "Nested class outside of class scope?");
18546569d68745c8213709740337d2be52b031384f58Douglas Gregor  ClassStack.top()->NestedClasses.push_back(Victim);
18556569d68745c8213709740337d2be52b031384f58Douglas Gregor  Victim->TemplateScope = CurScope->getParent()->isTemplateParamScope();
18566569d68745c8213709740337d2be52b031384f58Douglas Gregor}
1857bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1858bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// ParseCXX0XAttributes - Parse a C++0x attribute-specifier. Currently only
1859bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// parses standard attributes.
1860bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1861bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-specifier:
1862bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' '[' attribute-list ']' ']'
1863bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1864bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-list:
1865bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute[opt]
1866bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-list ',' attribute[opt]
1867bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1868bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute:
1869bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-token attribute-argument-clause[opt]
1870bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1871bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-token:
1872bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
1873bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-scoped-token
1874bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1875bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-scoped-token:
1876bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         attribute-namespace '::' identifier
1877bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1878bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-namespace:
1879bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         identifier
1880bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1881bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] attribute-argument-clause:
1882bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
1883bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1884bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] balanced-token-seq:
1885bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token
1886bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         balanced-token-seq balanced-token
1887bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
1888bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] balanced-token:
1889bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '(' balanced-token-seq ')'
1890bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '[' balanced-token-seq ']'
1891bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         '{' balanced-token-seq '}'
1892bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///         any token but '(', ')', '[', ']', '{', or '}'
1893bbd37c62e34db3f5a95c899723484a76c71d7757Sean HuntCXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
1894bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
1895bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      && "Not a C++0x attribute list");
1896bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1897bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  SourceLocation StartLoc = Tok.getLocation(), Loc;
1898bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  AttributeList *CurrAttr = 0;
1899bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1900bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
1901bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  ConsumeBracket();
1902193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1903bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (Tok.is(tok::comma)) {
1904bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    Diag(Tok.getLocation(), diag::err_expected_ident);
1905bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    ConsumeToken();
1906bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1907bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1908bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  while (Tok.is(tok::identifier) || Tok.is(tok::comma)) {
1909bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // attribute not present
1910bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::comma)) {
1911bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
1912bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      continue;
1913bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
1914bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1915bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    IdentifierInfo *ScopeName = 0, *AttrName = Tok.getIdentifierInfo();
1916bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceLocation ScopeLoc, AttrLoc = ConsumeToken();
1917193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1918bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // scoped attribute
1919bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (Tok.is(tok::coloncolon)) {
1920bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeToken();
1921bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1922bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      if (!Tok.is(tok::identifier)) {
1923bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        Diag(Tok.getLocation(), diag::err_expected_ident);
1924bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        SkipUntil(tok::r_square, tok::comma, true, true);
1925bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        continue;
1926bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
1927193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam
1928bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ScopeName = AttrName;
1929bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ScopeLoc = AttrLoc;
1930bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1931bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttrName = Tok.getIdentifierInfo();
1932bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      AttrLoc = ConsumeToken();
1933bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
1934bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1935bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    bool AttrParsed = false;
1936bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // No scoped names are supported; ideally we could put all non-standard
1937bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // attributes into namespaces.
1938bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (!ScopeName) {
1939bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      switch(AttributeList::getKind(AttrName))
1940bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      {
1941bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // No arguments
19427725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_base_check:
19437725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_carries_dependency:
1944bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      case AttributeList::AT_final:
19457725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_hiding:
19467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_noreturn:
19477725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt      case AttributeList::AT_override: {
1948bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        if (Tok.is(tok::l_paren)) {
1949bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          Diag(Tok.getLocation(), diag::err_cxx0x_attribute_forbids_arguments)
1950bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt            << AttrName->getName();
1951bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          break;
1952bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        }
1953bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1954bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        CurrAttr = new AttributeList(AttrName, AttrLoc, 0, AttrLoc, 0,
1955bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                     SourceLocation(), 0, 0, CurrAttr, false,
1956bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                     true);
1957bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        AttrParsed = true;
1958bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        break;
1959bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
1960bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1961bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // One argument; must be a type-id or assignment-expression
1962bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      case AttributeList::AT_aligned: {
1963bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        if (Tok.isNot(tok::l_paren)) {
1964bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          Diag(Tok.getLocation(), diag::err_cxx0x_attribute_requires_arguments)
1965bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt            << AttrName->getName();
1966bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt          break;
1967bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        }
1968bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        SourceLocation ParamLoc = ConsumeParen();
1969bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1970bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        OwningExprResult ArgExpr = ParseCXX0XAlignArgument(ParamLoc);
1971bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1972bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        MatchRHSPunctuation(tok::r_paren, ParamLoc);
1973bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1974bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        ExprVector ArgExprs(Actions);
1975bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        ArgExprs.push_back(ArgExpr.release());
1976bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        CurrAttr = new AttributeList(AttrName, AttrLoc, 0, AttrLoc,
1977bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                     0, ParamLoc, ArgExprs.take(), 1, CurrAttr,
1978bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                     false, true);
1979bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1980bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        AttrParsed = true;
1981bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt        break;
1982bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
1983bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1984bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // Silence warnings
1985bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      default: break;
1986bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      }
1987bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
1988bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1989bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    // Skip the entire parameter clause, if any
1990bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    if (!AttrParsed && Tok.is(tok::l_paren)) {
1991bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      ConsumeParen();
1992bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      // SkipUntil maintains the balancedness of tokens.
1993bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt      SkipUntil(tok::r_paren, false);
1994bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    }
1995bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  }
1996bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
1997bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
1998bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
1999bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  Loc = Tok.getLocation();
2000bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
2001bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SkipUntil(tok::r_square, false);
2002bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2003bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  CXX0XAttributeList Attr (CurrAttr, SourceRange(StartLoc, Loc), true);
2004bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  return Attr;
2005bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
2006bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt
2007bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// ParseCXX0XAlignArgument - Parse the argument to C++0x's [[align]]
2008bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute.
2009bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2010bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// FIXME: Simply returns an alignof() expression if the argument is a
2011bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// type. Ideally, the type should be propagated directly into Sema.
2012bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt///
2013bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] 'align' '(' type-id ')'
2014bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// [C++0x] 'align' '(' assignment-expression ')'
2015bbd37c62e34db3f5a95c899723484a76c71d7757Sean HuntParser::OwningExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) {
2016bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  if (isTypeIdInParens()) {
2017bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    EnterExpressionEvaluationContext Unevaluated(Actions,
2018bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                                  Action::Unevaluated);
2019bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceLocation TypeLoc = Tok.getLocation();
2020bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    TypeTy *Ty = ParseTypeName().get();
2021bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    SourceRange TypeRange(Start, Tok.getLocation());
2022bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return Actions.ActOnSizeOfAlignOfExpr(TypeLoc, false, true, Ty,
2023bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt                                              TypeRange);
2024bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt  } else
2025bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    return ParseConstantExpression();
2026bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt}
2027