ParseDeclCXX.cpp revision 39a8de10c18365bde7062d8959b7ed525449c561
18f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -----------------------===// 28f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 38f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// The LLVM Compiler Infrastructure 48f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 78f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 88f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===----------------------------------------------------------------------===// 98f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 108f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// This file implements the C++ Declaration portions of the Parser interfaces. 118f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 128f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===----------------------------------------------------------------------===// 138f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 141b7f89846f10681ce3cbe89ef5d60691d55bd918Douglas Gregor#include "clang/Parse/Parser.h" 15500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h" 16e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor#include "clang/Parse/DeclSpec.h" 178f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner#include "clang/Parse/Scope.h" 18a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl#include "AstGuard.h" 19bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner#include "ExtensionRAIIObject.h" 208f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattnerusing namespace clang; 218f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 228f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// ParseNamespace - We know that the current token is a namespace keyword. This 238f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// may either be a top level namespace or a block-level namespace alias. 248f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 258f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// namespace-definition: [C++ 7.3: basic.namespace] 268f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// named-namespace-definition 278f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// unnamed-namespace-definition 288f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 298f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// unnamed-namespace-definition: 308f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 'namespace' attributes[opt] '{' namespace-body '}' 318f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 328f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// named-namespace-definition: 338f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// original-namespace-definition 348f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// extension-namespace-definition 358f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 368f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// original-namespace-definition: 378f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 'namespace' identifier attributes[opt] '{' namespace-body '}' 388f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 398f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// extension-namespace-definition: 408f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 'namespace' original-namespace-name '{' namespace-body '}' 418f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 428f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// namespace-alias-definition: [C++ 7.3.2: namespace.alias] 438f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 'namespace' identifier '=' qualified-namespace-specifier ';' 448f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 458f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris LattnerParser::DeclTy *Parser::ParseNamespace(unsigned Context) { 4604d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner assert(Tok.is(tok::kw_namespace) && "Not a namespace!"); 478f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'. 488f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 498f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation IdentLoc; 508f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner IdentifierInfo *Ident = 0; 518f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 5204d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner if (Tok.is(tok::identifier)) { 538f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner Ident = Tok.getIdentifierInfo(); 548f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner IdentLoc = ConsumeToken(); // eat the identifier. 558f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner } 568f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 578f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner // Read label attributes, if present. 588f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner DeclTy *AttrList = 0; 5904d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner if (Tok.is(tok::kw___attribute)) 608f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner // FIXME: save these somewhere. 618f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner AttrList = ParseAttributes(); 628f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 6304d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner if (Tok.is(tok::equal)) { 648f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner // FIXME: Verify no attributes were present. 658f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner // FIXME: parse this. 6604d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner } else if (Tok.is(tok::l_brace)) { 672d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 688f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation LBrace = ConsumeBrace(); 692d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 702d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis // Enter a scope for the namespace. 718935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope NamespaceScope(this, Scope::DeclScope); 722d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 732d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis DeclTy *NamespcDecl = 742d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace); 752d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 762d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) 77bae35118fc5cea2da08567dbb9763af7f906dae2Chris Lattner ParseExternalDeclaration(); 788f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 798ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis // Leave the namespace scope. 808935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor NamespaceScope.Exit(); 818ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis 828f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace); 832d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis Actions.ActOnFinishNamespaceDef(NamespcDecl, RBrace); 842d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 852d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis return NamespcDecl; 868f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 878f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner } else { 881ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, Ident ? diag::err_expected_lbrace : 891ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner diag::err_expected_ident_lbrace); 908f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner } 918f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 928f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner return 0; 938f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner} 94c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 95c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal 96c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen. 97c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 98c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// linkage-specification: [C++ 7.5p2: dcl.link] 99c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 'extern' string-literal '{' declaration-seq[opt] '}' 100c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 'extern' string-literal declaration 101c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 102c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris LattnerParser::DeclTy *Parser::ParseLinkage(unsigned Context) { 103c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor assert(Tok.is(tok::string_literal) && "Not a string literal!"); 104c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner llvm::SmallVector<char, 8> LangBuffer; 105c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner // LangBuffer is guaranteed to be big enough. 106c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner LangBuffer.resize(Tok.getLength()); 107c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner const char *LangBufPtr = &LangBuffer[0]; 108c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner unsigned StrSize = PP.getSpelling(Tok, LangBufPtr); 109c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 110c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner SourceLocation Loc = ConsumeStringToken(); 111c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 112074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor ParseScope LinkageScope(this, Scope::DeclScope); 113074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor DeclTy *LinkageSpec 114074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor = Actions.ActOnStartLinkageSpecification(CurScope, 115074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor /*FIXME: */SourceLocation(), 116074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor Loc, LangBufPtr, StrSize, 117074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor Tok.is(tok::l_brace)? Tok.getLocation() 118074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor : SourceLocation()); 119074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor 120074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor if (Tok.isNot(tok::l_brace)) { 121074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor ParseDeclarationOrFunctionDefinition(); 122074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, 123074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor SourceLocation()); 124f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor } 125f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor 126f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor SourceLocation LBrace = ConsumeBrace(); 127f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 128074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor ParseExternalDeclaration(); 129f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor } 130c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 131f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace); 132074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, RBrace); 133c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner} 134e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 135f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or 136f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'. 1372f27477a29b6f5365ee545c1cac666cc8b95f518Chris LattnerParser::DeclTy *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context) { 138f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(Tok.is(tok::kw_using) && "Not using token"); 139f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 140f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Eat 'using'. 141f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation UsingLoc = ConsumeToken(); 142f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 1432f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner if (Tok.is(tok::kw_namespace)) 144f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Next token after 'using' is 'namespace' so it must be using-directive 145f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor return ParseUsingDirective(Context, UsingLoc); 1462f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner 1472f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner // Otherwise, it must be using-declaration. 1482f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner return ParseUsingDeclaration(Context, UsingLoc); 149f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 150f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 151f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes 152f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed. 153f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 154f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive: [C++ 7.3.p4: namespace.udir] 155f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'namespace' ::[opt] nested-name-specifier[opt] 156f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// namespace-name ; 157f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive: 158f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'namespace' ::[opt] nested-name-specifier[opt] 159f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// namespace-name attributes[opt] ; 160f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 161f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas GregorParser::DeclTy *Parser::ParseUsingDirective(unsigned Context, 162f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation UsingLoc) { 163f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token"); 164f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 165f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Eat 'namespace'. 166f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation NamespcLoc = ConsumeToken(); 167f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 168f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor CXXScopeSpec SS; 169f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Parse (optional) nested-name-specifier. 1707a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner ParseOptionalCXXScopeSpecifier(SS); 171f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 172f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor AttributeList *AttrList = 0; 173f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor IdentifierInfo *NamespcName = 0; 174f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation IdentLoc = SourceLocation(); 175f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 176f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Parse namespace-name. 177823c44e6d73141f642e207980b4021ddcf09897bChris Lattner if (SS.isInvalid() || Tok.isNot(tok::identifier)) { 178f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor Diag(Tok, diag::err_expected_namespace_name); 179f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // If there was invalid namespace name, skip to end of decl, and eat ';'. 180f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SkipUntil(tok::semi); 181f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // FIXME: Are there cases, when we would like to call ActOnUsingDirective? 182f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor return 0; 183f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor } 184823c44e6d73141f642e207980b4021ddcf09897bChris Lattner 185823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Parse identifier. 186823c44e6d73141f642e207980b4021ddcf09897bChris Lattner NamespcName = Tok.getIdentifierInfo(); 187823c44e6d73141f642e207980b4021ddcf09897bChris Lattner IdentLoc = ConsumeToken(); 188823c44e6d73141f642e207980b4021ddcf09897bChris Lattner 189823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Parse (optional) attributes (most likely GNU strong-using extension). 190823c44e6d73141f642e207980b4021ddcf09897bChris Lattner if (Tok.is(tok::kw___attribute)) 191823c44e6d73141f642e207980b4021ddcf09897bChris Lattner AttrList = ParseAttributes(); 192823c44e6d73141f642e207980b4021ddcf09897bChris Lattner 193823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Eat ';'. 194823c44e6d73141f642e207980b4021ddcf09897bChris Lattner ExpectAndConsume(tok::semi, diag::err_expected_semi_after, 195823c44e6d73141f642e207980b4021ddcf09897bChris Lattner AttrList ? "attributes list" : "namespace name", tok::semi); 196f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 197f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor return Actions.ActOnUsingDirective(CurScope, UsingLoc, NamespcLoc, SS, 198823c44e6d73141f642e207980b4021ddcf09897bChris Lattner IdentLoc, NamespcName, AttrList); 199f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 200f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 201f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that 202f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' was already seen. 203f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 204f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-declaration: [C++ 7.3.p3: namespace.udecl] 205f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'typename'[opt] ::[opt] nested-name-specifier 206f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// unqualified-id [TODO] 207f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' :: unqualified-id [TODO] 208f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 209f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas GregorParser::DeclTy *Parser::ParseUsingDeclaration(unsigned Context, 210f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation UsingLoc) { 211f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(false && "Not implemented"); 212f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // FIXME: Implement parsing. 213f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor return 0; 214f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 215f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 21642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// ParseClassName - Parse a C++ class-name, which names a class. Note 21742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// that we only check that the result names a type; semantic analysis 21842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// will need to verify that the type names a class. The result is 21942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// either a type or NULL, dependending on whether a type name was 22042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// found. 22142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// 22242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// class-name: [C++ 9.1] 22342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// identifier 22442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// template-id [TODO] 22542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// 226eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios KyrtzidisParser::TypeTy *Parser::ParseClassName(const CXXScopeSpec *SS) { 22742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Parse the class-name. 22842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // FIXME: Alternatively, parse a simple-template-id. 22942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor if (Tok.isNot(tok::identifier)) { 2301ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_class_name); 23142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return 0; 23242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor } 23342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 23442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // We have an identifier; check whether it is actually a type. 235b696ea3a0693798daeafd896d77f0b8f1fec3cc5Douglas Gregor TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(), 236b696ea3a0693798daeafd896d77f0b8f1fec3cc5Douglas Gregor Tok.getLocation(), CurScope, SS); 23742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor if (!Type) { 2381ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_class_name); 23942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return 0; 24042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor } 24142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 24242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Consume the identifier. 24342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor ConsumeToken(); 24442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 24542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return Type; 24642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor} 24742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 248e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or 249e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which 250e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that 251e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// cannot start a definition. 252e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 253e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-specifier: [C++ class] 254e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head '{' member-specification[opt] '}' 255e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head '{' member-specification[opt] '}' attributes[opt] 256e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head: 257e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key identifier[opt] base-clause[opt] 258e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key nested-name-specifier identifier base-clause[opt] 259e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key nested-name-specifier[opt] simple-template-id 260e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-clause[opt] 261e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] class-key attributes[opt] identifier[opt] base-clause[opt] 262e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] class-key attributes[opt] nested-name-specifier 263e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// identifier base-clause[opt] 264e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] class-key attributes[opt] nested-name-specifier[opt] 265e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// simple-template-id base-clause[opt] 266e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key: 267e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'class' 268e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'struct' 269e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'union' 270e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 271e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier: [C++ dcl.type.elab] 272e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key ::[opt] nested-name-specifier[opt] identifier 273e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key ::[opt] nested-name-specifier[opt] 'template'[opt] 274e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// simple-template-id 275e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 276e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// Note that the C++ class-specifier and elaborated-type-specifier, 277e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// together, subsume the C99 struct-or-union-specifier: 278e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 279e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union-specifier: [C99 6.7.2.1] 280e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union identifier[opt] '{' struct-contents '}' 281e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union identifier 282e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] struct-or-union attributes[opt] identifier[opt] '{' struct-contents 283e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// '}' attributes[opt] 284e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] struct-or-union attributes[opt] identifier 285e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union: 286e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'struct' 287e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'union' 288c4b4e7b8f6ca9b036824e048af49cd2a52b57cdfDouglas Gregorvoid Parser::ParseClassSpecifier(DeclSpec &DS, 289c4b4e7b8f6ca9b036824e048af49cd2a52b57cdfDouglas Gregor TemplateParameterLists *TemplateParams) { 290e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor assert((Tok.is(tok::kw_class) || 291e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Tok.is(tok::kw_struct) || 292e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Tok.is(tok::kw_union)) && 293e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor "Not a class specifier"); 294e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor DeclSpec::TST TagType = 295e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Tok.is(tok::kw_class) ? DeclSpec::TST_class : 296e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Tok.is(tok::kw_struct) ? DeclSpec::TST_struct : 297e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor DeclSpec::TST_union; 298e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 299e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation StartLoc = ConsumeToken(); 300e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 301e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor AttributeList *Attr = 0; 302e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If attributes exist after tag, parse them. 303e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw___attribute)) 304e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Attr = ParseAttributes(); 305e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 306f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff // If declspecs exist after tag, parse them. 307f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff if (Tok.is(tok::kw___declspec) && PP.getLangOptions().Microsoft) 308f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff FuzzyParseMicrosoftDeclSpec(); 309f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff 310eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Parse the (optional) nested-name-specifier. 311eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis CXXScopeSpec SS; 31239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS)) 31339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) 314eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis Diag(Tok, diag::err_expected_ident); 315cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor 316cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor // Parse the (optional) class name or simple-template-id. 317e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IdentifierInfo *Name = 0; 318e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation NameLoc; 31939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateIdAnnotation *TemplateId = 0; 320e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::identifier)) { 321e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Name = Tok.getIdentifierInfo(); 322e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor NameLoc = ConsumeToken(); 32339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor } else if (Tok.is(tok::annot_template_id)) { 32439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); 32539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor NameLoc = ConsumeToken(); 326cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor 32739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (TemplateId->Kind != TNK_Class_template) { 32839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // The template-name in the simple-template-id refers to 32939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // something other than a class template. Give an appropriate 33039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // error message and skip to the ';'. 33139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor SourceRange Range(NameLoc); 33239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (SS.isNotEmpty()) 33339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor Range.setBegin(SS.getBeginLoc()); 33439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor 33539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template) 33639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor << Name << static_cast<int>(TemplateId->Kind) << Range; 337cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor 33839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor DS.SetTypeSpecError(); 33939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor SkipUntil(tok::semi, false, true); 34039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->Destroy(); 34139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor return; 342cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor } 343e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 344e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 345e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // There are three options here. If we have 'struct foo;', then 346e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // this is a forward declaration. If we have 'struct foo {...' or 34739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // 'struct foo :...' then this is a definition. Otherwise we have 348e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // something like 'struct foo xyz', a reference. 349e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Action::TagKind TK; 350e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))) 351e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor TK = Action::TK_Definition; 352e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor else if (Tok.is(tok::semi)) 353e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor TK = Action::TK_Declaration; 354e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor else 355e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor TK = Action::TK_Reference; 356e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 35739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (!Name && !TemplateId && TK != Action::TK_Definition) { 358e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // We have a declaration or reference to an anonymous class. 3591ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(StartLoc, diag::err_anon_type_definition) 3601ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner << DeclSpec::getSpecifierName(TagType); 361e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 362e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Skip the rest of this declarator, up until the comma or semicolon. 363e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SkipUntil(tok::comma, true); 36439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor 36539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (TemplateId) 36639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->Destroy(); 367e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor return; 368e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 369e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 370ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor // Create the tag portion of the class or class template. 371ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor DeclTy *TagOrTempDecl; 37239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (TemplateId && TK != Action::TK_Reference) { 373cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor // Explicit specialization or class template partial 374cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor // specialization. Let semantic analysis decide. 37539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor ASTTemplateArgsPtr TemplateArgsPtr(Actions, 37639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->getTemplateArgs(), 37739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->getTemplateArgIsType(), 37839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->NumArgs); 379cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor TagOrTempDecl 380cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TK, 38139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor StartLoc, SS, 38239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->Template, 38339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->TemplateNameLoc, 38439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->LAngleLoc, 38539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateArgsPtr, 38639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->getTemplateArgLocations(), 38739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->RAngleLoc, 38839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor Attr, 389cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor Action::MultiTemplateParamsArg(Actions, 390cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor TemplateParams? &(*TemplateParams)[0] : 0, 391cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor TemplateParams? TemplateParams->size() : 0)); 39239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->Destroy(); 39339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor } else if (TemplateParams && TK != Action::TK_Reference) 394ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor TagOrTempDecl = Actions.ActOnClassTemplate(CurScope, TagType, TK, StartLoc, 395ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor SS, Name, NameLoc, Attr, 396ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor Action::MultiTemplateParamsArg(Actions, 397ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor &(*TemplateParams)[0], 398ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor TemplateParams->size())); 399ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor else 400ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor TagOrTempDecl = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS, Name, 401ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor NameLoc, Attr); 402e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 403e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the optional base clause (C++ only). 40422bd905673a73ccb9b5e45a7038ec060c9650ffeChris Lattner if (getLang().CPlusPlus && Tok.is(tok::colon)) 405aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor ParseBaseClause(TagOrTempDecl); 406e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 407e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If there is a body, parse it and inform the actions module. 408e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::l_brace)) 40907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis if (getLang().CPlusPlus) 410aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempDecl); 41107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis else 412aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor ParseStructUnionBody(StartLoc, TagType, TagOrTempDecl); 413e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor else if (TK == Action::TK_Definition) { 414e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // FIXME: Complain that we have a base-specifier list but no 415e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // definition. 4161ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_lbrace); 417e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 418e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 419e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor const char *PrevSpec = 0; 420ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor if (!TagOrTempDecl) 421ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor DS.SetTypeSpecError(); 422ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor else if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, TagOrTempDecl)) 4231ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec; 424e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 425e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 426e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived]. 427e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 428e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-clause : [C++ class.derived] 429e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ':' base-specifier-list 430e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier-list: 431e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier '...'[opt] 432e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier-list ',' base-specifier '...'[opt] 433e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregorvoid Parser::ParseBaseClause(DeclTy *ClassDecl) 434e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor{ 435e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor assert(Tok.is(tok::colon) && "Not a base clause"); 436e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 437e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 438f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Build up an array of parsed base specifiers. 439f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor llvm::SmallVector<BaseTy *, 8> BaseInfo; 440f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor 441e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor while (true) { 442e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse a base-specifier. 443f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor BaseResult Result = ParseBaseSpecifier(ClassDecl); 4445ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor if (Result.isInvalid()) { 445e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Skip the rest of this base specifier, up until the comma or 446e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // opening brace. 447f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor SkipUntil(tok::comma, tok::l_brace, true, true); 448f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor } else { 449f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Add this to our array of base specifiers. 4505ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor BaseInfo.push_back(Result.get()); 451e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 452e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 453e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If the next token is a comma, consume it and keep reading 454e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // base-specifiers. 455e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.isNot(tok::comma)) break; 456e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 457e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Consume the comma. 458e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 459e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 460f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor 461f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Attach the base specifiers 462f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor Actions.ActOnBaseSpecifiers(ClassDecl, &BaseInfo[0], BaseInfo.size()); 463e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 464e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 465e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is 466e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example: 467e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class foo : public bar, virtual private baz { 468e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers. 469e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 470e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier: [C++ class.derived] 471e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ::[opt] nested-name-specifier[opt] class-name 472e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt] 473e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-name 474e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt] 475e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-name 476f8268ae3196002bbab6adb830302e79b0f368f13Douglas GregorParser::BaseResult Parser::ParseBaseSpecifier(DeclTy *ClassDecl) 477e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor{ 478e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor bool IsVirtual = false; 479e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation StartLoc = Tok.getLocation(); 480e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 481e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the 'virtual' keyword. 482e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw_virtual)) { 483e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 484e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IsVirtual = true; 485e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 486e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 487e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse an (optional) access specifier. 488e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor AccessSpecifier Access = getAccessSpecifierIfPresent(); 489e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Access) 490e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 491e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 492e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the 'virtual' keyword (again!), in case it came after the 493e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // access specifier. 494e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw_virtual)) { 495e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation VirtualLoc = ConsumeToken(); 496e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (IsVirtual) { 497e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Complain about duplicate 'virtual' 4981ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(VirtualLoc, diag::err_dup_virtual) 4991ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner << SourceRange(VirtualLoc, VirtualLoc); 500e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 501e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 502e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IsVirtual = true; 503e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 504e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 505eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Parse optional '::' and optional nested-name-specifier. 506eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis CXXScopeSpec SS; 5077a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner ParseOptionalCXXScopeSpecifier(SS); 508e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 509e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // The location of the base class itself. 510e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation BaseLoc = Tok.getLocation(); 51142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 51242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Parse the class-name. 513eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis TypeTy *BaseType = ParseClassName(&SS); 51442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor if (!BaseType) 51542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return true; 516e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 517e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Find the complete source range for the base-specifier. 518e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceRange Range(StartLoc, BaseLoc); 519e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 520e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Notify semantic analysis that we have parsed a complete 521e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // base-specifier. 522a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access, 523a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl BaseType, BaseLoc); 524e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 525e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 526e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is 527e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier. 528e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 529e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// access-specifier: [C++ class.derived] 530e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'private' 531e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'protected' 532e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public' 5331b7f89846f10681ce3cbe89ef5d60691d55bd918Douglas GregorAccessSpecifier Parser::getAccessSpecifierIfPresent() const 534e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor{ 535e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor switch (Tok.getKind()) { 536e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor default: return AS_none; 537e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_private: return AS_private; 538e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_protected: return AS_protected; 539e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_public: return AS_public; 540e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 541e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 5424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 5434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration. 5444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 5454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declaration: 5464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// decl-specifier-seq[opt] member-declarator-list[opt] ';' 5474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// function-definition ';'[opt] 5484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO] 5494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// using-declaration [TODO] 5504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// [C++0x] static_assert-declaration [TODO] 5514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// template-declaration [TODO] 552bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU] '__extension__' member-declaration 5534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 5544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator-list: 5554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator 5564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator-list ',' member-declarator 5574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 5584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator: 5594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// declarator pure-specifier[opt] 5604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// declarator constant-initializer[opt] 5614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// identifier[opt] ':' constant-expression 5624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 5634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// pure-specifier: [TODO] 5644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// '= 0' 5654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 5664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// constant-initializer: 5674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// '=' constant-expression 5684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 5694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios KyrtzidisParser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) { 570bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner // Handle: member-declaration ::= '__extension__' member-declaration 571bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner if (Tok.is(tok::kw___extension__)) { 572bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner // __extension__ silences extension warnings in the subexpression. 573bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner ExtensionRAIIObject O(Diags); // Use RAII to do this. 574bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner ConsumeToken(); 575bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner return ParseCXXClassMemberDeclaration(AS); 576bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner } 577bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner 5784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation DSStart = Tok.getLocation(); 5794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // decl-specifier-seq: 5804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the common declaration-specifiers piece. 5814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclSpec DS; 5824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ParseDeclarationSpecifiers(DS); 5834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 5844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) { 5854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 5864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // C++ 9.2p7: The member-declarator-list can be omitted only after a 5874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // class-specifier or an enum-specifier or in a friend declaration. 5884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // FIXME: Friend declarations. 5894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis switch (DS.getTypeSpecType()) { 5904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case DeclSpec::TST_struct: 5914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case DeclSpec::TST_union: 5924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case DeclSpec::TST_class: 5934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case DeclSpec::TST_enum: 5944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return Actions.ParsedFreeStandingDeclSpec(CurScope, DS); 5954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis default: 5964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Diag(DSStart, diag::err_no_declarators); 5974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return 0; 5984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 5994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 60007952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis 6014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::MemberContext); 6024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6033a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.isNot(tok::colon)) { 6043a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // Parse the first declarator. 6053a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 6063a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // Error parsing the declarator? 60710bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor if (!DeclaratorInfo.hasName()) { 6083a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // If so, skip until the semi-colon or a }. 6094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::r_brace, true); 6103a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.is(tok::semi)) 6113a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeToken(); 6124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return 0; 6134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 6144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6153a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // function-definition: 6167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.is(tok::l_brace) 6177ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor || (DeclaratorInfo.isFunctionDeclarator() && Tok.is(tok::colon))) { 6183a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (!DeclaratorInfo.isFunctionDeclarator()) { 6193a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis Diag(Tok, diag::err_func_def_no_params); 6203a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeBrace(); 6213a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis SkipUntil(tok::r_brace, true); 6223a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis return 0; 6233a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 6243a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis 6253a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 6263a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis Diag(Tok, diag::err_function_declared_typedef); 6273a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // This recovery skips the entire function body. It would be nice 6283a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // to simply call ParseCXXInlineMethodDef() below, however Sema 6293a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // assumes the declarator represents a function, not a typedef. 6303a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeBrace(); 6313a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis SkipUntil(tok::r_brace, true); 6323a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis return 0; 6333a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 6344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6353a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis return ParseCXXInlineMethodDef(AS, DeclaratorInfo); 6363a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 6374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 6384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator-list: 6404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator 6414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator-list ',' member-declarator 6424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclTy *LastDeclInGroup = 0; 64415faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult BitfieldSize(Actions); 64515faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Init(Actions); 6464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis while (1) { 6484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator: 6504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // declarator pure-specifier[opt] 6514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // declarator constant-initializer[opt] 6524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // identifier[opt] ':' constant-expression 6534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::colon)) { 6554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 6560e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl BitfieldSize = ParseConstantExpression(); 6570e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (BitfieldSize.isInvalid()) 6584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::comma, true, true); 6594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 6604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // pure-specifier: 6624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // '= 0' 6634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // 6644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // constant-initializer: 6654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // '=' constant-expression 6664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::equal)) { 6684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 6690e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl Init = ParseInitializer(); 6700e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Init.isInvalid()) 6714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::comma, true, true); 6724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 6734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If attributes exist after the declarator, parse them. 675ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl if (Tok.is(tok::kw___attribute)) { 676ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl SourceLocation Loc; 677ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl AttributeList *AttrList = ParseAttributes(&Loc); 678ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl DeclaratorInfo.AddAttributes(AttrList, Loc); 679ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl } 6804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 68107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // NOTE: If Sema is the Action module and declarator is an instance field, 68207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // this call will *not* return the created decl; LastDeclInGroup will be 68307952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // returned instead. 68407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // See Sema::ActOnCXXMemberDeclarator for details. 6854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis LastDeclInGroup = Actions.ActOnCXXMemberDeclarator(CurScope, AS, 6864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclaratorInfo, 687effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl BitfieldSize.release(), 688effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Init.release(), 6894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis LastDeclInGroup); 6904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 69172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (DeclaratorInfo.isFunctionDeclarator() && 69272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor DeclaratorInfo.getDeclSpec().getStorageClassSpec() 69372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor != DeclSpec::SCS_typedef) { 69472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // We just declared a member function. If this member function 69572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // has any default arguments, we'll need to parse them later. 69672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateParsedMethodDeclaration *LateMethod = 0; 69772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor DeclaratorChunk::FunctionTypeInfo &FTI 69872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor = DeclaratorInfo.getTypeObject(0).Fun; 69972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) { 70072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) { 70172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (!LateMethod) { 70272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Push this method onto the stack of late-parsed method 70372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // declarations. 70472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor getCurTopClassStack().MethodDecls.push_back( 70572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateParsedMethodDeclaration(LastDeclInGroup)); 70672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateMethod = &getCurTopClassStack().MethodDecls.back(); 70772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 70872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Add all of the parameters prior to this one (they don't 70972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // have default arguments). 71072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateMethod->DefaultArgs.reserve(FTI.NumArgs); 71172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor for (unsigned I = 0; I < ParamIdx; ++I) 71272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateMethod->DefaultArgs.push_back( 71372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param)); 71472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 71572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 71672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Add this parameter to the list of parameters (it or may 71772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // not have a default argument). 71872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateMethod->DefaultArgs.push_back( 71972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param, 72072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor FTI.ArgInfo[ParamIdx].DefaultArgTokens)); 72172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 72272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 72372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 72472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 7254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If we don't have a comma, it is either the end of the list (a ';') 7264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // or an error, bail out. 7274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.isNot(tok::comma)) 7284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 7294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Consume the comma. 7314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 7324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the next declarator. 7344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclaratorInfo.clear(); 73515faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl BitfieldSize = 0; 73615faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl Init = 0; 7374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Attributes are only allowed on the second declarator. 739ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl if (Tok.is(tok::kw___attribute)) { 740ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl SourceLocation Loc; 741ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl AttributeList *AttrList = ParseAttributes(&Loc); 742ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl DeclaratorInfo.AddAttributes(AttrList, Loc); 743ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl } 7444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7453a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.isNot(tok::colon)) 7463a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 7474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 7484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) { 7504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 7514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Reverse the chain list. 7524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup); 7534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 7544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Diag(Tok, diag::err_expected_semi_decl_list); 7564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Skip to end of block or statement 7574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::r_brace, true, true); 7584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) 7594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 7604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return 0; 7614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 7624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition. 7644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 7654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-specification: 7664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declaration member-specification[opt] 7674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// access-specifier ':' member-specification[opt] 7684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 7694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidisvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, 7704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis unsigned TagType, DeclTy *TagDecl) { 77131fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta assert((TagType == DeclSpec::TST_struct || 7724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis TagType == DeclSpec::TST_union || 77331fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta TagType == DeclSpec::TST_class) && "Invalid TagType!"); 7744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation LBraceLoc = ConsumeBrace(); 7764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7773218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor if (!CurScope->isClassScope() && // Not about to define a nested class. 7784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurScope->isInCXXInlineMethodScope()) { 7794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // We will define a local class of an inline method. 7804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Push a new LexedMethodsForTopClass for its inline methods. 7814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis PushTopClassStack(); 7824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 7834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Enter a scope for the class. 7853218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope); 7864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 787ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor if (TagDecl) 788ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor Actions.ActOnTagStartDefinition(CurScope, TagDecl); 789ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor else { 790ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor SkipUntil(tok::r_brace, false, false); 791ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor return; 792ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor } 7934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // C++ 11p3: Members of a class defined with the keyword class are private 7954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // by default. Members of a class defined with the keywords struct or union 7964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // are public by default. 7974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AccessSpecifier CurAS; 7984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (TagType == DeclSpec::TST_class) 7994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS_private; 8004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis else 8014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS_public; 8024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // While we still have something to read, read the member-declarations. 8044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 8054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Each iteration of this loop reads one member-declaration. 8064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Check for extraneous top-level semicolon. 8084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) { 8094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Diag(Tok, diag::ext_extra_struct_semi); 8104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 8114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis continue; 8124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 8134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AccessSpecifier AS = getAccessSpecifierIfPresent(); 8154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (AS != AS_none) { 8164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Current token is a C++ access specifier. 8174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS; 8184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 8194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ExpectAndConsume(tok::colon, diag::err_expected_colon); 8204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis continue; 8214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 8224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse all the comma separated declarators. 8244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ParseCXXClassMemberDeclaration(CurAS); 8254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 8264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); 8284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AttributeList *AttrList = 0; 8304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If attributes exist after class contents, parse them. 8314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 8324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AttrList = ParseAttributes(); // FIXME: where should I put them? 8334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl, 8354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis LBraceLoc, RBraceLoc); 8364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // C++ 9.2p2: Within the class member-specification, the class is regarded as 8384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // complete within function bodies, default arguments, 8394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // exception-specifications, and constructor ctor-initializers (including 8404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // such things in nested classes). 8414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // 84272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // FIXME: Only function bodies and constructor ctor-initializers are 84372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // parsed correctly, fix the rest. 8443218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor if (!CurScope->getParent()->isClassScope()) { 8454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // We are not inside a nested class. This class and its nested classes 84672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // are complete and we can parse the delayed portions of method 84772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // declarations and the lexed inline method definitions. 84872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor ParseLexedMethodDeclarations(); 8494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ParseLexedMethodDefs(); 8504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // For a local class of inline method, pop the LexedMethodsForTopClass that 8524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // was previously pushed. 8534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 85431fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta assert((CurScope->isInCXXInlineMethodScope() || 85531fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta TopClassStacks.size() == 1) && 8564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis "MethodLexers not getting popped properly!"); 8574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (CurScope->isInCXXInlineMethodScope()) 8584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis PopTopClassStack(); 8594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 8604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Leave the class scope. 8628935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ClassScope.Exit(); 8634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 86472de6676bd30f9081ee4166bbe07b4c270258ce6Douglas Gregor Actions.ActOnTagFinishDefinition(CurScope, TagDecl); 8654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 8667ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8677ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer, 8687ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a 8697ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers 8707ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below: 8717ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 8727ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code 8737ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { }; 8747ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base { 8757ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// int x; 8767ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// float f; 8777ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public: 8787ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// Derived(float f) : Base(), x(17), f(f) { } 8797ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// }; 8807ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode 8817ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 8827ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] ctor-initializer: 8837ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ':' mem-initializer-list 8847ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 8857ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-list: 8867ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// mem-initializer 8877ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// mem-initializer , mem-initializer-list 8887ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregorvoid Parser::ParseConstructorInitializer(DeclTy *ConstructorDecl) { 8897ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'"); 8907ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8917ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation ColonLoc = ConsumeToken(); 8927ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8937ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor llvm::SmallVector<MemInitTy*, 4> MemInitializers; 8947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8957ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor do { 8967ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); 8975ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor if (!MemInit.isInvalid()) 8985ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor MemInitializers.push_back(MemInit.get()); 8997ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9007ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.is(tok::comma)) 9017ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor ConsumeToken(); 9027ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor else if (Tok.is(tok::l_brace)) 9037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor break; 9047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor else { 9057ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Skip over garbage, until we get to '{'. Don't eat the '{'. 9067ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SkipUntil(tok::l_brace, true, true); 9077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor break; 9087ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 9097ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } while (true); 9107ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9117ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, 9127ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor &MemInitializers[0], MemInitializers.size()); 9137ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor} 9147ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9157ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is 9167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one 9177ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See 9187ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example. 9197ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 9207ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer: 9217ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// mem-initializer-id '(' expression-list[opt] ')' 9227ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 9237ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id: 9247ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// '::'[opt] nested-name-specifier[opt] class-name 9257ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// identifier 9267ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas GregorParser::MemInitResult Parser::ParseMemInitializer(DeclTy *ConstructorDecl) { 9277ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // FIXME: parse '::'[opt] nested-name-specifier[opt] 9287ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9297ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.isNot(tok::identifier)) { 9301ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_member_or_base_name); 9317ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor return true; 9327ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 9337ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9347ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Get the identifier. This may be a member name or a class name, 9357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // but we'll let the semantic analysis determine which it is. 9367ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor IdentifierInfo *II = Tok.getIdentifierInfo(); 9377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation IdLoc = ConsumeToken(); 9387ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9397ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Parse the '('. 9407ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.isNot(tok::l_paren)) { 9411ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_lparen); 9427ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor return true; 9437ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 9447ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation LParenLoc = ConsumeParen(); 9457ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9467ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Parse the optional expression-list. 947a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector ArgExprs(Actions); 9487ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor CommaLocsTy CommaLocs; 9497ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) { 9507ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SkipUntil(tok::r_paren); 9517ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor return true; 9527ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 9537ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9547ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 9557ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 956a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, II, IdLoc, 957a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl LParenLoc, ArgExprs.take(), 958a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ArgExprs.size(), &CommaLocs[0], RParenLoc); 9597ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor} 9600fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 9610fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// ParseExceptionSpecification - Parse a C++ exception-specification 9620fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// (C++ [except.spec]). 9630fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 964a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// exception-specification: 965a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// 'throw' '(' type-id-list [opt] ')' 966a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS] 'throw' '(' '...' ')' 9670fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 968a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// type-id-list: 969a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// type-id 970a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// type-id-list ',' type-id 9710fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 972ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redlbool Parser::ParseExceptionSpecification(SourceLocation &EndLoc) { 9730fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor assert(Tok.is(tok::kw_throw) && "expected throw"); 9740fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 9750fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor SourceLocation ThrowLoc = ConsumeToken(); 9760fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 9770fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor if (!Tok.is(tok::l_paren)) { 9780fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor return Diag(Tok, diag::err_expected_lparen_after) << "throw"; 9790fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor } 9800fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor SourceLocation LParenLoc = ConsumeParen(); 9810fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 982a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor // Parse throw(...), a Microsoft extension that means "this function 983a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor // can throw anything". 984a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor if (Tok.is(tok::ellipsis)) { 985a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor SourceLocation EllipsisLoc = ConsumeToken(); 986a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor if (!getLang().Microsoft) 987a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec); 988ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 989a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor return false; 990a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor } 991a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor 9920fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor // Parse the sequence of type-ids. 9930fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor while (Tok.isNot(tok::r_paren)) { 9940fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor ParseTypeName(); 9950fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor if (Tok.is(tok::comma)) 9960fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor ConsumeToken(); 9970fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor else 9980fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor break; 9990fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor } 10000fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 1001ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 10020fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor return false; 10030fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor} 1004