ParseDeclCXX.cpp revision 94b15fbc3a10cdfb1639528a8a773b66a1e7cd9e
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 7649f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions, 7749f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner PP.getSourceManager(), 7849f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner "parsing namespace"); 792254a9f32830492459a6fc4d90ccd2776dab7807Chris Lattner 802d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) 81bae35118fc5cea2da08567dbb9763af7f906dae2Chris Lattner ParseExternalDeclaration(); 828f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 838ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis // Leave the namespace scope. 848935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor NamespaceScope.Exit(); 858ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis 868f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace); 872d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis Actions.ActOnFinishNamespaceDef(NamespcDecl, RBrace); 882d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 892d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis return NamespcDecl; 908f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 918f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner } else { 921ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, Ident ? diag::err_expected_lbrace : 931ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner diag::err_expected_ident_lbrace); 948f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner } 958f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 968f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner return 0; 978f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner} 98c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 99c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal 100c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen. 101c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 102c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// linkage-specification: [C++ 7.5p2: dcl.link] 103c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 'extern' string-literal '{' declaration-seq[opt] '}' 104c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 'extern' string-literal declaration 105c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 106c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris LattnerParser::DeclTy *Parser::ParseLinkage(unsigned Context) { 107c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor assert(Tok.is(tok::string_literal) && "Not a string literal!"); 108c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner llvm::SmallVector<char, 8> LangBuffer; 109c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner // LangBuffer is guaranteed to be big enough. 110c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner LangBuffer.resize(Tok.getLength()); 111c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner const char *LangBufPtr = &LangBuffer[0]; 112c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner unsigned StrSize = PP.getSpelling(Tok, LangBufPtr); 113c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 114c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner SourceLocation Loc = ConsumeStringToken(); 115c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 116074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor ParseScope LinkageScope(this, Scope::DeclScope); 117074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor DeclTy *LinkageSpec 118074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor = Actions.ActOnStartLinkageSpecification(CurScope, 119074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor /*FIXME: */SourceLocation(), 120074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor Loc, LangBufPtr, StrSize, 121074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor Tok.is(tok::l_brace)? Tok.getLocation() 122074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor : SourceLocation()); 123074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor 124074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor if (Tok.isNot(tok::l_brace)) { 125074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor ParseDeclarationOrFunctionDefinition(); 126074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, 127074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor SourceLocation()); 128f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor } 129f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor 130f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor SourceLocation LBrace = ConsumeBrace(); 131f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 132074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor ParseExternalDeclaration(); 133f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor } 134c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 135f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace); 136074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, RBrace); 137c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner} 138e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 139f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or 140f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'. 1412f27477a29b6f5365ee545c1cac666cc8b95f518Chris LattnerParser::DeclTy *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context) { 142f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(Tok.is(tok::kw_using) && "Not using token"); 143f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 144f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Eat 'using'. 145f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation UsingLoc = ConsumeToken(); 146f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 1472f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner if (Tok.is(tok::kw_namespace)) 148f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Next token after 'using' is 'namespace' so it must be using-directive 149f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor return ParseUsingDirective(Context, UsingLoc); 1502f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner 1512f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner // Otherwise, it must be using-declaration. 1522f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner return ParseUsingDeclaration(Context, UsingLoc); 153f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 154f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 155f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes 156f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed. 157f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 158f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive: [C++ 7.3.p4: namespace.udir] 159f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'namespace' ::[opt] nested-name-specifier[opt] 160f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// namespace-name ; 161f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive: 162f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'namespace' ::[opt] nested-name-specifier[opt] 163f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// namespace-name attributes[opt] ; 164f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 165f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas GregorParser::DeclTy *Parser::ParseUsingDirective(unsigned Context, 166f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation UsingLoc) { 167f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token"); 168f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 169f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Eat 'namespace'. 170f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation NamespcLoc = ConsumeToken(); 171f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 172f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor CXXScopeSpec SS; 173f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Parse (optional) nested-name-specifier. 1747a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner ParseOptionalCXXScopeSpecifier(SS); 175f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 176f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor AttributeList *AttrList = 0; 177f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor IdentifierInfo *NamespcName = 0; 178f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation IdentLoc = SourceLocation(); 179f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 180f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Parse namespace-name. 181823c44e6d73141f642e207980b4021ddcf09897bChris Lattner if (SS.isInvalid() || Tok.isNot(tok::identifier)) { 182f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor Diag(Tok, diag::err_expected_namespace_name); 183f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // If there was invalid namespace name, skip to end of decl, and eat ';'. 184f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SkipUntil(tok::semi); 185f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // FIXME: Are there cases, when we would like to call ActOnUsingDirective? 186f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor return 0; 187f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor } 188823c44e6d73141f642e207980b4021ddcf09897bChris Lattner 189823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Parse identifier. 190823c44e6d73141f642e207980b4021ddcf09897bChris Lattner NamespcName = Tok.getIdentifierInfo(); 191823c44e6d73141f642e207980b4021ddcf09897bChris Lattner IdentLoc = ConsumeToken(); 192823c44e6d73141f642e207980b4021ddcf09897bChris Lattner 193823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Parse (optional) attributes (most likely GNU strong-using extension). 194823c44e6d73141f642e207980b4021ddcf09897bChris Lattner if (Tok.is(tok::kw___attribute)) 195823c44e6d73141f642e207980b4021ddcf09897bChris Lattner AttrList = ParseAttributes(); 196823c44e6d73141f642e207980b4021ddcf09897bChris Lattner 197823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Eat ';'. 198823c44e6d73141f642e207980b4021ddcf09897bChris Lattner ExpectAndConsume(tok::semi, diag::err_expected_semi_after, 199823c44e6d73141f642e207980b4021ddcf09897bChris Lattner AttrList ? "attributes list" : "namespace name", tok::semi); 200f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 201f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor return Actions.ActOnUsingDirective(CurScope, UsingLoc, NamespcLoc, SS, 202823c44e6d73141f642e207980b4021ddcf09897bChris Lattner IdentLoc, NamespcName, AttrList); 203f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 204f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 205f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that 206f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' was already seen. 207f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 208f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-declaration: [C++ 7.3.p3: namespace.udecl] 209f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'typename'[opt] ::[opt] nested-name-specifier 210f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// unqualified-id [TODO] 211f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' :: unqualified-id [TODO] 212f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 213f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas GregorParser::DeclTy *Parser::ParseUsingDeclaration(unsigned Context, 214f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation UsingLoc) { 215f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(false && "Not implemented"); 216f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // FIXME: Implement parsing. 217f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor return 0; 218f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 219f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 220511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion. 221511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// 222511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// static_assert-declaration: 223511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// static_assert ( constant-expression , string-literal ) ; 224511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// 225511d7aba3b12853fdb88729a0313b80a60eab8adAnders CarlssonParser::DeclTy *Parser::ParseStaticAssertDeclaration() { 226511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration"); 227511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson SourceLocation StaticAssertLoc = ConsumeToken(); 228511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 229511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson if (Tok.isNot(tok::l_paren)) { 230511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson Diag(Tok, diag::err_expected_lparen); 231511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson return 0; 232511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 233511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 234511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson SourceLocation LParenLoc = ConsumeParen(); 235511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 236511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson OwningExprResult AssertExpr(ParseConstantExpression()); 237511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson if (AssertExpr.isInvalid()) { 238511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson SkipUntil(tok::semi); 239511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson return 0; 240511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 241511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 242ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi)) 243511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson return 0; 244ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson 245511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson if (Tok.isNot(tok::string_literal)) { 246511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson Diag(Tok, diag::err_expected_string_literal); 247511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson SkipUntil(tok::semi); 248511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson return 0; 249511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 250511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 251511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson OwningExprResult AssertMessage(ParseStringLiteralExpression()); 252511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson if (AssertMessage.isInvalid()) 253511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson return 0; 254511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 25594b15fbc3a10cdfb1639528a8a773b66a1e7cd9eAnders Carlsson MatchRHSPunctuation(tok::r_paren, LParenLoc); 256511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 257511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert); 258511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 259ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, move(AssertExpr), 26094b15fbc3a10cdfb1639528a8a773b66a1e7cd9eAnders Carlsson move(AssertMessage)); 261511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson} 262511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 26342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// ParseClassName - Parse a C++ class-name, which names a class. Note 26442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// that we only check that the result names a type; semantic analysis 26542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// will need to verify that the type names a class. The result is 2667f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor/// either a type or NULL, depending on whether a type name was 26742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// found. 26842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// 26942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// class-name: [C++ 9.1] 27042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// identifier 2717f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor/// simple-template-id 27242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// 2737f43d6764797ab21216421aeb00f4ec314d503d1Douglas GregorParser::TypeTy *Parser::ParseClassName(SourceLocation &EndLocation, 2747f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor const CXXScopeSpec *SS) { 2757f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor // Check whether we have a template-id that names a type. 2767f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor if (Tok.is(tok::annot_template_id)) { 2777f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor TemplateIdAnnotation *TemplateId 2787f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); 2797f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor if (TemplateId->Kind == TNK_Class_template) { 2807f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor if (AnnotateTemplateIdTokenAsType(SS)) 2817f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor return 0; 2827f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 2837f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); 2847f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor TypeTy *Type = Tok.getAnnotationValue(); 2857f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor EndLocation = Tok.getAnnotationEndLoc(); 2867f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor ConsumeToken(); 2877f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor return Type; 2887f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor } 2897f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 2907f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor // Fall through to produce an error below. 2917f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor } 2927f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 29342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor if (Tok.isNot(tok::identifier)) { 2941ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_class_name); 29542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return 0; 29642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor } 29742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 29842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // We have an identifier; check whether it is actually a type. 299b696ea3a0693798daeafd896d77f0b8f1fec3cc5Douglas Gregor TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(), 300b696ea3a0693798daeafd896d77f0b8f1fec3cc5Douglas Gregor Tok.getLocation(), CurScope, SS); 30142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor if (!Type) { 3021ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_class_name); 30342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return 0; 30442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor } 30542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 30642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Consume the identifier. 3077f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor EndLocation = ConsumeToken(); 30842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return Type; 30942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor} 31042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 311e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or 312e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which 313e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that 314e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// cannot start a definition. 315e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 316e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-specifier: [C++ class] 317e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head '{' member-specification[opt] '}' 318e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head '{' member-specification[opt] '}' attributes[opt] 319e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head: 320e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key identifier[opt] base-clause[opt] 321e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key nested-name-specifier identifier base-clause[opt] 322e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key nested-name-specifier[opt] simple-template-id 323e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-clause[opt] 324e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] class-key attributes[opt] identifier[opt] base-clause[opt] 325e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] class-key attributes[opt] nested-name-specifier 326e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// identifier base-clause[opt] 327e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] class-key attributes[opt] nested-name-specifier[opt] 328e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// simple-template-id base-clause[opt] 329e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key: 330e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'class' 331e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'struct' 332e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'union' 333e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 334e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier: [C++ dcl.type.elab] 335e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key ::[opt] nested-name-specifier[opt] identifier 336e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key ::[opt] nested-name-specifier[opt] 'template'[opt] 337e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// simple-template-id 338e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 339e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// Note that the C++ class-specifier and elaborated-type-specifier, 340e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// together, subsume the C99 struct-or-union-specifier: 341e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 342e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union-specifier: [C99 6.7.2.1] 343e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union identifier[opt] '{' struct-contents '}' 344e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union identifier 345e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] struct-or-union attributes[opt] identifier[opt] '{' struct-contents 346e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// '}' attributes[opt] 347e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] struct-or-union attributes[opt] identifier 348e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union: 349e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'struct' 350e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'union' 351c4b4e7b8f6ca9b036824e048af49cd2a52b57cdfDouglas Gregorvoid Parser::ParseClassSpecifier(DeclSpec &DS, 352c4b4e7b8f6ca9b036824e048af49cd2a52b57cdfDouglas Gregor TemplateParameterLists *TemplateParams) { 353e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor assert((Tok.is(tok::kw_class) || 354e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Tok.is(tok::kw_struct) || 355e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Tok.is(tok::kw_union)) && 356e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor "Not a class specifier"); 357e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor DeclSpec::TST TagType = 358e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Tok.is(tok::kw_class) ? DeclSpec::TST_class : 359e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Tok.is(tok::kw_struct) ? DeclSpec::TST_struct : 360e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor DeclSpec::TST_union; 361e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 362e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation StartLoc = ConsumeToken(); 363e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 364e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor AttributeList *Attr = 0; 365e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If attributes exist after tag, parse them. 366e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw___attribute)) 367e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Attr = ParseAttributes(); 368e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 369f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff // If declspecs exist after tag, parse them. 370f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff if (Tok.is(tok::kw___declspec) && PP.getLangOptions().Microsoft) 371f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff FuzzyParseMicrosoftDeclSpec(); 372f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff 373eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Parse the (optional) nested-name-specifier. 374eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis CXXScopeSpec SS; 37539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS)) 37639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) 377eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis Diag(Tok, diag::err_expected_ident); 378cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor 379cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor // Parse the (optional) class name or simple-template-id. 380e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IdentifierInfo *Name = 0; 381e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation NameLoc; 38239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateIdAnnotation *TemplateId = 0; 383e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::identifier)) { 384e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Name = Tok.getIdentifierInfo(); 385e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor NameLoc = ConsumeToken(); 38639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor } else if (Tok.is(tok::annot_template_id)) { 38739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); 38839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor NameLoc = ConsumeToken(); 389cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor 39039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (TemplateId->Kind != TNK_Class_template) { 39139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // The template-name in the simple-template-id refers to 39239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // something other than a class template. Give an appropriate 39339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // error message and skip to the ';'. 39439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor SourceRange Range(NameLoc); 39539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (SS.isNotEmpty()) 39639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor Range.setBegin(SS.getBeginLoc()); 39739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor 39839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template) 39939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor << Name << static_cast<int>(TemplateId->Kind) << Range; 400cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor 40139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor DS.SetTypeSpecError(); 40239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor SkipUntil(tok::semi, false, true); 40339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->Destroy(); 40439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor return; 405cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor } 406e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 407e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 408e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // There are three options here. If we have 'struct foo;', then 409e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // this is a forward declaration. If we have 'struct foo {...' or 41039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // 'struct foo :...' then this is a definition. Otherwise we have 411e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // something like 'struct foo xyz', a reference. 412e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Action::TagKind TK; 413e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))) 414e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor TK = Action::TK_Definition; 415e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor else if (Tok.is(tok::semi)) 416e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor TK = Action::TK_Declaration; 417e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor else 418e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor TK = Action::TK_Reference; 419e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 42039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (!Name && !TemplateId && TK != Action::TK_Definition) { 421e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // We have a declaration or reference to an anonymous class. 4221ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(StartLoc, diag::err_anon_type_definition) 4231ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner << DeclSpec::getSpecifierName(TagType); 424e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 425e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Skip the rest of this declarator, up until the comma or semicolon. 426e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SkipUntil(tok::comma, true); 42739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor 42839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (TemplateId) 42939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->Destroy(); 430e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor return; 431e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 432e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 433ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor // Create the tag portion of the class or class template. 434ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor DeclTy *TagOrTempDecl; 43539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (TemplateId && TK != Action::TK_Reference) { 436cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor // Explicit specialization or class template partial 437cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor // specialization. Let semantic analysis decide. 43839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor ASTTemplateArgsPtr TemplateArgsPtr(Actions, 43939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->getTemplateArgs(), 44039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->getTemplateArgIsType(), 44139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->NumArgs); 442cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor TagOrTempDecl 443cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor = Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TK, 44439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor StartLoc, SS, 44539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->Template, 44639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->TemplateNameLoc, 44739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->LAngleLoc, 44839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateArgsPtr, 44939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->getTemplateArgLocations(), 45039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->RAngleLoc, 45139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor Attr, 452cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor Action::MultiTemplateParamsArg(Actions, 453cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor TemplateParams? &(*TemplateParams)[0] : 0, 454cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor TemplateParams? TemplateParams->size() : 0)); 45539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->Destroy(); 45639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor } else if (TemplateParams && TK != Action::TK_Reference) 457ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor TagOrTempDecl = Actions.ActOnClassTemplate(CurScope, TagType, TK, StartLoc, 458ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor SS, Name, NameLoc, Attr, 459ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor Action::MultiTemplateParamsArg(Actions, 460ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor &(*TemplateParams)[0], 461ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor TemplateParams->size())); 462ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor else 463ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor TagOrTempDecl = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS, Name, 464ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor NameLoc, Attr); 465e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 466e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the optional base clause (C++ only). 46722bd905673a73ccb9b5e45a7038ec060c9650ffeChris Lattner if (getLang().CPlusPlus && Tok.is(tok::colon)) 468aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor ParseBaseClause(TagOrTempDecl); 469e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 470e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If there is a body, parse it and inform the actions module. 471e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::l_brace)) 47207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis if (getLang().CPlusPlus) 473aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempDecl); 47407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis else 475aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregor ParseStructUnionBody(StartLoc, TagType, TagOrTempDecl); 476e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor else if (TK == Action::TK_Definition) { 477e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // FIXME: Complain that we have a base-specifier list but no 478e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // definition. 4791ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_lbrace); 480e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 481e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 482e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor const char *PrevSpec = 0; 483ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor if (!TagOrTempDecl) 484ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor DS.SetTypeSpecError(); 485ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor else if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, TagOrTempDecl)) 4861ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec; 487e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 488e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 489e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived]. 490e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 491e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-clause : [C++ class.derived] 492e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ':' base-specifier-list 493e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier-list: 494e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier '...'[opt] 495e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier-list ',' base-specifier '...'[opt] 496e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregorvoid Parser::ParseBaseClause(DeclTy *ClassDecl) 497e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor{ 498e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor assert(Tok.is(tok::colon) && "Not a base clause"); 499e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 500e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 501f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Build up an array of parsed base specifiers. 502f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor llvm::SmallVector<BaseTy *, 8> BaseInfo; 503f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor 504e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor while (true) { 505e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse a base-specifier. 506f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor BaseResult Result = ParseBaseSpecifier(ClassDecl); 5075ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor if (Result.isInvalid()) { 508e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Skip the rest of this base specifier, up until the comma or 509e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // opening brace. 510f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor SkipUntil(tok::comma, tok::l_brace, true, true); 511f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor } else { 512f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Add this to our array of base specifiers. 5135ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor BaseInfo.push_back(Result.get()); 514e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 515e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 516e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If the next token is a comma, consume it and keep reading 517e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // base-specifiers. 518e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.isNot(tok::comma)) break; 519e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 520e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Consume the comma. 521e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 522e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 523f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor 524f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Attach the base specifiers 525f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor Actions.ActOnBaseSpecifiers(ClassDecl, &BaseInfo[0], BaseInfo.size()); 526e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 527e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 528e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is 529e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example: 530e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class foo : public bar, virtual private baz { 531e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers. 532e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 533e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier: [C++ class.derived] 534e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ::[opt] nested-name-specifier[opt] class-name 535e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt] 536e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-name 537e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt] 538e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-name 539f8268ae3196002bbab6adb830302e79b0f368f13Douglas GregorParser::BaseResult Parser::ParseBaseSpecifier(DeclTy *ClassDecl) 540e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor{ 541e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor bool IsVirtual = false; 542e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation StartLoc = Tok.getLocation(); 543e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 544e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the 'virtual' keyword. 545e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw_virtual)) { 546e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 547e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IsVirtual = true; 548e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 549e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 550e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse an (optional) access specifier. 551e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor AccessSpecifier Access = getAccessSpecifierIfPresent(); 552e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Access) 553e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 554e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 555e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the 'virtual' keyword (again!), in case it came after the 556e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // access specifier. 557e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw_virtual)) { 558e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation VirtualLoc = ConsumeToken(); 559e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (IsVirtual) { 560e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Complain about duplicate 'virtual' 5611ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(VirtualLoc, diag::err_dup_virtual) 5621ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner << SourceRange(VirtualLoc, VirtualLoc); 563e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 564e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 565e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IsVirtual = true; 566e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 567e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 568eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Parse optional '::' and optional nested-name-specifier. 569eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis CXXScopeSpec SS; 5707a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner ParseOptionalCXXScopeSpecifier(SS); 571e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 572e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // The location of the base class itself. 573e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation BaseLoc = Tok.getLocation(); 57442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 57542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Parse the class-name. 5767f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor SourceLocation EndLocation; 5777f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor TypeTy *BaseType = ParseClassName(EndLocation, &SS); 57842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor if (!BaseType) 57942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return true; 580e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 581e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Find the complete source range for the base-specifier. 5827f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor SourceRange Range(StartLoc, EndLocation); 583e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 584e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Notify semantic analysis that we have parsed a complete 585e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // base-specifier. 586a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access, 587a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl BaseType, BaseLoc); 588e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 589e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 590e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is 591e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier. 592e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 593e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// access-specifier: [C++ class.derived] 594e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'private' 595e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'protected' 596e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public' 5971b7f89846f10681ce3cbe89ef5d60691d55bd918Douglas GregorAccessSpecifier Parser::getAccessSpecifierIfPresent() const 598e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor{ 599e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor switch (Tok.getKind()) { 600e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor default: return AS_none; 601e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_private: return AS_private; 602e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_protected: return AS_protected; 603e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_public: return AS_public; 604e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 605e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 6064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration. 6084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 6094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declaration: 6104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// decl-specifier-seq[opt] member-declarator-list[opt] ';' 6114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// function-definition ';'[opt] 6124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO] 6134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// using-declaration [TODO] 614511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration 6154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// template-declaration [TODO] 616bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU] '__extension__' member-declaration 6174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 6184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator-list: 6194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator 6204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator-list ',' member-declarator 6214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 6224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator: 6234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// declarator pure-specifier[opt] 6244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// declarator constant-initializer[opt] 6254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// identifier[opt] ':' constant-expression 6264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 6274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// pure-specifier: [TODO] 6284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// '= 0' 6294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 6304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// constant-initializer: 6314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// '=' constant-expression 6324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 6334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios KyrtzidisParser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) { 634511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson // static_assert-declaration 635511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson if (Tok.is(tok::kw_static_assert)) 636511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson return ParseStaticAssertDeclaration(); 637511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 638bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner // Handle: member-declaration ::= '__extension__' member-declaration 639bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner if (Tok.is(tok::kw___extension__)) { 640bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner // __extension__ silences extension warnings in the subexpression. 641bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner ExtensionRAIIObject O(Diags); // Use RAII to do this. 642bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner ConsumeToken(); 643bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner return ParseCXXClassMemberDeclaration(AS); 644bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner } 645bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner 6464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation DSStart = Tok.getLocation(); 6474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // decl-specifier-seq: 6484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the common declaration-specifiers piece. 6494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclSpec DS; 6504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ParseDeclarationSpecifiers(DS); 6514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) { 6534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 6544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // C++ 9.2p7: The member-declarator-list can be omitted only after a 6554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // class-specifier or an enum-specifier or in a friend declaration. 6564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // FIXME: Friend declarations. 6574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis switch (DS.getTypeSpecType()) { 6584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case DeclSpec::TST_struct: 6594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case DeclSpec::TST_union: 6604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case DeclSpec::TST_class: 6614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case DeclSpec::TST_enum: 6624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return Actions.ParsedFreeStandingDeclSpec(CurScope, DS); 6634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis default: 6644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Diag(DSStart, diag::err_no_declarators); 6654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return 0; 6664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 6674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 66807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis 6694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::MemberContext); 6704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6713a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.isNot(tok::colon)) { 6723a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // Parse the first declarator. 6733a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 6743a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // Error parsing the declarator? 67510bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor if (!DeclaratorInfo.hasName()) { 6763a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // If so, skip until the semi-colon or a }. 6774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::r_brace, true); 6783a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.is(tok::semi)) 6793a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeToken(); 6804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return 0; 6814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 6824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6833a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // function-definition: 6847ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.is(tok::l_brace) 6857ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor || (DeclaratorInfo.isFunctionDeclarator() && Tok.is(tok::colon))) { 6863a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (!DeclaratorInfo.isFunctionDeclarator()) { 6873a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis Diag(Tok, diag::err_func_def_no_params); 6883a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeBrace(); 6893a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis SkipUntil(tok::r_brace, true); 6903a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis return 0; 6913a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 6923a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis 6933a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 6943a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis Diag(Tok, diag::err_function_declared_typedef); 6953a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // This recovery skips the entire function body. It would be nice 6963a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // to simply call ParseCXXInlineMethodDef() below, however Sema 6973a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // assumes the declarator represents a function, not a typedef. 6983a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeBrace(); 6993a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis SkipUntil(tok::r_brace, true); 7003a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis return 0; 7013a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 7024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7033a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis return ParseCXXInlineMethodDef(AS, DeclaratorInfo); 7043a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 7054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 7064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator-list: 7084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator 7094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator-list ',' member-declarator 7104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclTy *LastDeclInGroup = 0; 71215faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult BitfieldSize(Actions); 71315faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Init(Actions); 7144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis while (1) { 7164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator: 7184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // declarator pure-specifier[opt] 7194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // declarator constant-initializer[opt] 7204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // identifier[opt] ':' constant-expression 7214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::colon)) { 7234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 7240e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl BitfieldSize = ParseConstantExpression(); 7250e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (BitfieldSize.isInvalid()) 7264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::comma, true, true); 7274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 7284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // pure-specifier: 7304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // '= 0' 7314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // 7324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // constant-initializer: 7334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // '=' constant-expression 7344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::equal)) { 7364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 7370e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl Init = ParseInitializer(); 7380e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Init.isInvalid()) 7394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::comma, true, true); 7404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 7414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If attributes exist after the declarator, parse them. 743ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl if (Tok.is(tok::kw___attribute)) { 744ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl SourceLocation Loc; 745ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl AttributeList *AttrList = ParseAttributes(&Loc); 746ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl DeclaratorInfo.AddAttributes(AttrList, Loc); 747ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl } 7484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 74907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // NOTE: If Sema is the Action module and declarator is an instance field, 75007952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // this call will *not* return the created decl; LastDeclInGroup will be 75107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // returned instead. 75207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // See Sema::ActOnCXXMemberDeclarator for details. 7534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis LastDeclInGroup = Actions.ActOnCXXMemberDeclarator(CurScope, AS, 7544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclaratorInfo, 755effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl BitfieldSize.release(), 756effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Init.release(), 7574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis LastDeclInGroup); 7584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 75972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (DeclaratorInfo.isFunctionDeclarator() && 76072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor DeclaratorInfo.getDeclSpec().getStorageClassSpec() 76172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor != DeclSpec::SCS_typedef) { 76272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // We just declared a member function. If this member function 76372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // has any default arguments, we'll need to parse them later. 76472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateParsedMethodDeclaration *LateMethod = 0; 76572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor DeclaratorChunk::FunctionTypeInfo &FTI 76672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor = DeclaratorInfo.getTypeObject(0).Fun; 76772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) { 76872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) { 76972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (!LateMethod) { 77072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Push this method onto the stack of late-parsed method 77172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // declarations. 77272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor getCurTopClassStack().MethodDecls.push_back( 77372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateParsedMethodDeclaration(LastDeclInGroup)); 77472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateMethod = &getCurTopClassStack().MethodDecls.back(); 77572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 77672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Add all of the parameters prior to this one (they don't 77772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // have default arguments). 77872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateMethod->DefaultArgs.reserve(FTI.NumArgs); 77972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor for (unsigned I = 0; I < ParamIdx; ++I) 78072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateMethod->DefaultArgs.push_back( 78172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param)); 78272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 78372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 78472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Add this parameter to the list of parameters (it or may 78572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // not have a default argument). 78672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateMethod->DefaultArgs.push_back( 78772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param, 78872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor FTI.ArgInfo[ParamIdx].DefaultArgTokens)); 78972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 79072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 79172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 79272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 7934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If we don't have a comma, it is either the end of the list (a ';') 7944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // or an error, bail out. 7954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.isNot(tok::comma)) 7964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 7974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Consume the comma. 7994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 8004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the next declarator. 8024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclaratorInfo.clear(); 80315faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl BitfieldSize = 0; 80415faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl Init = 0; 8054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Attributes are only allowed on the second declarator. 807ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl if (Tok.is(tok::kw___attribute)) { 808ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl SourceLocation Loc; 809ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl AttributeList *AttrList = ParseAttributes(&Loc); 810ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl DeclaratorInfo.AddAttributes(AttrList, Loc); 811ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl } 8124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8133a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.isNot(tok::colon)) 8143a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 8154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 8164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) { 8184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 8194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Reverse the chain list. 8204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup); 8214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 8224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Diag(Tok, diag::err_expected_semi_decl_list); 8244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Skip to end of block or statement 8254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::r_brace, true, true); 8264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) 8274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 8284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return 0; 8294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 8304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition. 8324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 8334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-specification: 8344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declaration member-specification[opt] 8354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// access-specifier ':' member-specification[opt] 8364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 8374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidisvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, 8384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis unsigned TagType, DeclTy *TagDecl) { 83931fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta assert((TagType == DeclSpec::TST_struct || 8404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis TagType == DeclSpec::TST_union || 84131fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta TagType == DeclSpec::TST_class) && "Invalid TagType!"); 8424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 84349f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions, 84449f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner PP.getSourceManager(), 84549f28ca787d8db7cac3c8898334f70ea55374c98Chris Lattner "parsing struct/union/class body"); 84627b7f1028255149978356f85c4825522d234a253Chris Lattner 8474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation LBraceLoc = ConsumeBrace(); 8484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8493218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor if (!CurScope->isClassScope() && // Not about to define a nested class. 8504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurScope->isInCXXInlineMethodScope()) { 8514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // We will define a local class of an inline method. 8524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Push a new LexedMethodsForTopClass for its inline methods. 8534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis PushTopClassStack(); 8544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 8554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Enter a scope for the class. 8573218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope); 8584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 859ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor if (TagDecl) 860ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor Actions.ActOnTagStartDefinition(CurScope, TagDecl); 861ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor else { 862ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor SkipUntil(tok::r_brace, false, false); 863ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor return; 864ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor } 8654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // C++ 11p3: Members of a class defined with the keyword class are private 8674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // by default. Members of a class defined with the keywords struct or union 8684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // are public by default. 8694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AccessSpecifier CurAS; 8704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (TagType == DeclSpec::TST_class) 8714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS_private; 8724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis else 8734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS_public; 8744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // While we still have something to read, read the member-declarations. 8764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 8774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Each iteration of this loop reads one member-declaration. 8784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Check for extraneous top-level semicolon. 8804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) { 8814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Diag(Tok, diag::ext_extra_struct_semi); 8824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 8834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis continue; 8844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 8854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AccessSpecifier AS = getAccessSpecifierIfPresent(); 8874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (AS != AS_none) { 8884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Current token is a C++ access specifier. 8894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS; 8904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 8914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ExpectAndConsume(tok::colon, diag::err_expected_colon); 8924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis continue; 8934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 8944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse all the comma separated declarators. 8964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ParseCXXClassMemberDeclaration(CurAS); 8974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 8984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); 9004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 9014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AttributeList *AttrList = 0; 9024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If attributes exist after class contents, parse them. 9034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 9044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AttrList = ParseAttributes(); // FIXME: where should I put them? 9054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 9064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl, 9074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis LBraceLoc, RBraceLoc); 9084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 9094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // C++ 9.2p2: Within the class member-specification, the class is regarded as 9104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // complete within function bodies, default arguments, 9114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // exception-specifications, and constructor ctor-initializers (including 9124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // such things in nested classes). 9134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // 91472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // FIXME: Only function bodies and constructor ctor-initializers are 91572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // parsed correctly, fix the rest. 9163218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor if (!CurScope->getParent()->isClassScope()) { 9174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // We are not inside a nested class. This class and its nested classes 91872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // are complete and we can parse the delayed portions of method 91972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // declarations and the lexed inline method definitions. 92072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor ParseLexedMethodDeclarations(); 9214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ParseLexedMethodDefs(); 9224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 9234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // For a local class of inline method, pop the LexedMethodsForTopClass that 9244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // was previously pushed. 9254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 92631fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta assert((CurScope->isInCXXInlineMethodScope() || 92731fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta TopClassStacks.size() == 1) && 9284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis "MethodLexers not getting popped properly!"); 9294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (CurScope->isInCXXInlineMethodScope()) 9304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis PopTopClassStack(); 9314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 9324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 9334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Leave the class scope. 9348935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ClassScope.Exit(); 9354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 93672de6676bd30f9081ee4166bbe07b4c270258ce6Douglas Gregor Actions.ActOnTagFinishDefinition(CurScope, TagDecl); 9374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 9387ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9397ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer, 9407ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a 9417ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers 9427ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below: 9437ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 9447ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code 9457ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { }; 9467ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base { 9477ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// int x; 9487ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// float f; 9497ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public: 9507ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// Derived(float f) : Base(), x(17), f(f) { } 9517ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// }; 9527ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode 9537ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 9547ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] ctor-initializer: 9557ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ':' mem-initializer-list 9567ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 9577ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-list: 9587ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// mem-initializer 9597ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// mem-initializer , mem-initializer-list 9607ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregorvoid Parser::ParseConstructorInitializer(DeclTy *ConstructorDecl) { 9617ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'"); 9627ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9637ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation ColonLoc = ConsumeToken(); 9647ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9657ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor llvm::SmallVector<MemInitTy*, 4> MemInitializers; 9667ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9677ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor do { 9687ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); 9695ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor if (!MemInit.isInvalid()) 9705ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor MemInitializers.push_back(MemInit.get()); 9717ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9727ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.is(tok::comma)) 9737ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor ConsumeToken(); 9747ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor else if (Tok.is(tok::l_brace)) 9757ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor break; 9767ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor else { 9777ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Skip over garbage, until we get to '{'. Don't eat the '{'. 9787ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SkipUntil(tok::l_brace, true, true); 9797ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor break; 9807ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 9817ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } while (true); 9827ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9837ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, 9847ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor &MemInitializers[0], MemInitializers.size()); 9857ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor} 9867ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 9877ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is 9887ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one 9897ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See 9907ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example. 9917ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 9927ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer: 9937ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// mem-initializer-id '(' expression-list[opt] ')' 9947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 9957ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id: 9967ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// '::'[opt] nested-name-specifier[opt] class-name 9977ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// identifier 9987ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas GregorParser::MemInitResult Parser::ParseMemInitializer(DeclTy *ConstructorDecl) { 9997ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // FIXME: parse '::'[opt] nested-name-specifier[opt] 10007ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 10017ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.isNot(tok::identifier)) { 10021ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_member_or_base_name); 10037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor return true; 10047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 10057ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 10067ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Get the identifier. This may be a member name or a class name, 10077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // but we'll let the semantic analysis determine which it is. 10087ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor IdentifierInfo *II = Tok.getIdentifierInfo(); 10097ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation IdLoc = ConsumeToken(); 10107ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 10117ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Parse the '('. 10127ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.isNot(tok::l_paren)) { 10131ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_lparen); 10147ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor return true; 10157ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 10167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation LParenLoc = ConsumeParen(); 10177ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 10187ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Parse the optional expression-list. 1019a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector ArgExprs(Actions); 10207ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor CommaLocsTy CommaLocs; 10217ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) { 10227ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SkipUntil(tok::r_paren); 10237ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor return true; 10247ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 10257ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 10267ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 10277ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 1028a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, II, IdLoc, 1029a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl LParenLoc, ArgExprs.take(), 1030a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ArgExprs.size(), &CommaLocs[0], RParenLoc); 10317ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor} 10320fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 10330fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// ParseExceptionSpecification - Parse a C++ exception-specification 10340fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// (C++ [except.spec]). 10350fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 1036a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// exception-specification: 1037a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// 'throw' '(' type-id-list [opt] ')' 1038a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS] 'throw' '(' '...' ')' 10390fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 1040a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// type-id-list: 1041a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// type-id 1042a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// type-id-list ',' type-id 10430fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 1044ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redlbool Parser::ParseExceptionSpecification(SourceLocation &EndLoc) { 10450fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor assert(Tok.is(tok::kw_throw) && "expected throw"); 10460fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 10470fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor SourceLocation ThrowLoc = ConsumeToken(); 10480fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 10490fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor if (!Tok.is(tok::l_paren)) { 10500fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor return Diag(Tok, diag::err_expected_lparen_after) << "throw"; 10510fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor } 10520fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor SourceLocation LParenLoc = ConsumeParen(); 10530fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 1054a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor // Parse throw(...), a Microsoft extension that means "this function 1055a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor // can throw anything". 1056a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor if (Tok.is(tok::ellipsis)) { 1057a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor SourceLocation EllipsisLoc = ConsumeToken(); 1058a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor if (!getLang().Microsoft) 1059a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec); 1060ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 1061a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor return false; 1062a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor } 1063a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor 10640fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor // Parse the sequence of type-ids. 10650fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor while (Tok.isNot(tok::r_paren)) { 10660fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor ParseTypeName(); 10670fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor if (Tok.is(tok::comma)) 10680fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor ConsumeToken(); 10690fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor else 10700fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor break; 10710fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor } 10720fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 1073ab197baec16bacade82325fb274cf6b992ac5d8aSebastian Redl EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 10740fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor return false; 10750fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor} 1076