ParseDeclCXX.cpp revision b696ea3a0693798daeafd896d77f0b8f1fec3cc5
18f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -----------------------===// 28f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 38f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// The LLVM Compiler Infrastructure 48f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 78f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 88f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===----------------------------------------------------------------------===// 98f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 108f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// This file implements the C++ Declaration portions of the Parser interfaces. 118f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 128f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===----------------------------------------------------------------------===// 138f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 141b7f89846f10681ce3cbe89ef5d60691d55bd918Douglas Gregor#include "clang/Parse/Parser.h" 15500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h" 16e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor#include "clang/Parse/DeclSpec.h" 178f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner#include "clang/Parse/Scope.h" 18a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl#include "AstGuard.h" 19bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner#include "ExtensionRAIIObject.h" 208f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattnerusing namespace clang; 218f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 228f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// ParseNamespace - We know that the current token is a namespace keyword. This 238f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// may either be a top level namespace or a block-level namespace alias. 248f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 258f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// namespace-definition: [C++ 7.3: basic.namespace] 268f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// named-namespace-definition 278f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// unnamed-namespace-definition 288f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 298f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// unnamed-namespace-definition: 308f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 'namespace' attributes[opt] '{' namespace-body '}' 318f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 328f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// named-namespace-definition: 338f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// original-namespace-definition 348f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// extension-namespace-definition 358f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 368f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// original-namespace-definition: 378f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 'namespace' identifier attributes[opt] '{' namespace-body '}' 388f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 398f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// extension-namespace-definition: 408f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 'namespace' original-namespace-name '{' namespace-body '}' 418f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 428f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// namespace-alias-definition: [C++ 7.3.2: namespace.alias] 438f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 'namespace' identifier '=' qualified-namespace-specifier ';' 448f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 458f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris LattnerParser::DeclTy *Parser::ParseNamespace(unsigned Context) { 4604d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner assert(Tok.is(tok::kw_namespace) && "Not a namespace!"); 478f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'. 488f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 498f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation IdentLoc; 508f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner IdentifierInfo *Ident = 0; 518f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 5204d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner if (Tok.is(tok::identifier)) { 538f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner Ident = Tok.getIdentifierInfo(); 548f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner IdentLoc = ConsumeToken(); // eat the identifier. 558f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner } 568f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 578f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner // Read label attributes, if present. 588f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner DeclTy *AttrList = 0; 5904d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner if (Tok.is(tok::kw___attribute)) 608f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner // FIXME: save these somewhere. 618f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner AttrList = ParseAttributes(); 628f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 6304d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner if (Tok.is(tok::equal)) { 648f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner // FIXME: Verify no attributes were present. 658f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner // FIXME: parse this. 6604d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner } else if (Tok.is(tok::l_brace)) { 672d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 688f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation LBrace = ConsumeBrace(); 692d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 702d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis // Enter a scope for the namespace. 718935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope NamespaceScope(this, Scope::DeclScope); 722d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 732d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis DeclTy *NamespcDecl = 742d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis Actions.ActOnStartNamespaceDef(CurScope, IdentLoc, Ident, LBrace); 752d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 762d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) 77bae35118fc5cea2da08567dbb9763af7f906dae2Chris Lattner ParseExternalDeclaration(); 788f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 798ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis // Leave the namespace scope. 808935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor NamespaceScope.Exit(); 818ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis 828f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace); 832d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis Actions.ActOnFinishNamespaceDef(NamespcDecl, RBrace); 842d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 852d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis return NamespcDecl; 868f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 878f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner } else { 881ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, Ident ? diag::err_expected_lbrace : 891ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner diag::err_expected_ident_lbrace); 908f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner } 918f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 928f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner return 0; 938f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner} 94c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 95c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal 96c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen. 97c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 98c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// linkage-specification: [C++ 7.5p2: dcl.link] 99c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 'extern' string-literal '{' declaration-seq[opt] '}' 100c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 'extern' string-literal declaration 101c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 102c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris LattnerParser::DeclTy *Parser::ParseLinkage(unsigned Context) { 103c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor assert(Tok.is(tok::string_literal) && "Not a string literal!"); 104c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner llvm::SmallVector<char, 8> LangBuffer; 105c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner // LangBuffer is guaranteed to be big enough. 106c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner LangBuffer.resize(Tok.getLength()); 107c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner const char *LangBufPtr = &LangBuffer[0]; 108c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner unsigned StrSize = PP.getSpelling(Tok, LangBufPtr); 109c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 110c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner SourceLocation Loc = ConsumeStringToken(); 111c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 112074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor ParseScope LinkageScope(this, Scope::DeclScope); 113074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor DeclTy *LinkageSpec 114074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor = Actions.ActOnStartLinkageSpecification(CurScope, 115074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor /*FIXME: */SourceLocation(), 116074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor Loc, LangBufPtr, StrSize, 117074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor Tok.is(tok::l_brace)? Tok.getLocation() 118074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor : SourceLocation()); 119074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor 120074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor if (Tok.isNot(tok::l_brace)) { 121074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor ParseDeclarationOrFunctionDefinition(); 122074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, 123074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor SourceLocation()); 124f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor } 125f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor 126f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor SourceLocation LBrace = ConsumeBrace(); 127f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 128074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor ParseExternalDeclaration(); 129f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor } 130c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 131f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace); 132074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor return Actions.ActOnFinishLinkageSpecification(CurScope, LinkageSpec, RBrace); 133c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner} 134e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 135f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or 136f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'. 1372f27477a29b6f5365ee545c1cac666cc8b95f518Chris LattnerParser::DeclTy *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context) { 138f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(Tok.is(tok::kw_using) && "Not using token"); 139f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 140f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Eat 'using'. 141f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation UsingLoc = ConsumeToken(); 142f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 1432f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner if (Tok.is(tok::kw_namespace)) 144f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Next token after 'using' is 'namespace' so it must be using-directive 145f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor return ParseUsingDirective(Context, UsingLoc); 1462f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner 1472f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner // Otherwise, it must be using-declaration. 1482f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner return ParseUsingDeclaration(Context, UsingLoc); 149f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 150f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 151f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes 152f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed. 153f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 154f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive: [C++ 7.3.p4: namespace.udir] 155f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'namespace' ::[opt] nested-name-specifier[opt] 156f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// namespace-name ; 157f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive: 158f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'namespace' ::[opt] nested-name-specifier[opt] 159f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// namespace-name attributes[opt] ; 160f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 161f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas GregorParser::DeclTy *Parser::ParseUsingDirective(unsigned Context, 162f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation UsingLoc) { 163f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token"); 164f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 165f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Eat 'namespace'. 166f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation NamespcLoc = ConsumeToken(); 167f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 168f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor CXXScopeSpec SS; 169f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Parse (optional) nested-name-specifier. 1707a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner ParseOptionalCXXScopeSpecifier(SS); 171f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 172f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor AttributeList *AttrList = 0; 173f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor IdentifierInfo *NamespcName = 0; 174f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation IdentLoc = SourceLocation(); 175f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 176f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Parse namespace-name. 177823c44e6d73141f642e207980b4021ddcf09897bChris Lattner if (SS.isInvalid() || Tok.isNot(tok::identifier)) { 178f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor Diag(Tok, diag::err_expected_namespace_name); 179f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // If there was invalid namespace name, skip to end of decl, and eat ';'. 180f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SkipUntil(tok::semi); 181f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // FIXME: Are there cases, when we would like to call ActOnUsingDirective? 182f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor return 0; 183f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor } 184823c44e6d73141f642e207980b4021ddcf09897bChris Lattner 185823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Parse identifier. 186823c44e6d73141f642e207980b4021ddcf09897bChris Lattner NamespcName = Tok.getIdentifierInfo(); 187823c44e6d73141f642e207980b4021ddcf09897bChris Lattner IdentLoc = ConsumeToken(); 188823c44e6d73141f642e207980b4021ddcf09897bChris Lattner 189823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Parse (optional) attributes (most likely GNU strong-using extension). 190823c44e6d73141f642e207980b4021ddcf09897bChris Lattner if (Tok.is(tok::kw___attribute)) 191823c44e6d73141f642e207980b4021ddcf09897bChris Lattner AttrList = ParseAttributes(); 192823c44e6d73141f642e207980b4021ddcf09897bChris Lattner 193823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Eat ';'. 194823c44e6d73141f642e207980b4021ddcf09897bChris Lattner ExpectAndConsume(tok::semi, diag::err_expected_semi_after, 195823c44e6d73141f642e207980b4021ddcf09897bChris Lattner AttrList ? "attributes list" : "namespace name", tok::semi); 196f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 197f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor return Actions.ActOnUsingDirective(CurScope, UsingLoc, NamespcLoc, SS, 198823c44e6d73141f642e207980b4021ddcf09897bChris Lattner IdentLoc, NamespcName, AttrList); 199f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 200f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 201f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that 202f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' was already seen. 203f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 204f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-declaration: [C++ 7.3.p3: namespace.udecl] 205f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'typename'[opt] ::[opt] nested-name-specifier 206f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// unqualified-id [TODO] 207f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' :: unqualified-id [TODO] 208f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 209f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas GregorParser::DeclTy *Parser::ParseUsingDeclaration(unsigned Context, 210f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation UsingLoc) { 211f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(false && "Not implemented"); 212f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // FIXME: Implement parsing. 213f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor return 0; 214f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 215f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 21642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// ParseClassName - Parse a C++ class-name, which names a class. Note 21742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// that we only check that the result names a type; semantic analysis 21842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// will need to verify that the type names a class. The result is 21942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// either a type or NULL, dependending on whether a type name was 22042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// found. 22142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// 22242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// class-name: [C++ 9.1] 22342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// identifier 22442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// template-id [TODO] 22542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// 226eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios KyrtzidisParser::TypeTy *Parser::ParseClassName(const CXXScopeSpec *SS) { 22742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Parse the class-name. 22842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // FIXME: Alternatively, parse a simple-template-id. 22942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor if (Tok.isNot(tok::identifier)) { 2301ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_class_name); 23142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return 0; 23242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor } 23342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 23442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // We have an identifier; check whether it is actually a type. 235b696ea3a0693798daeafd896d77f0b8f1fec3cc5Douglas Gregor TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(), 236b696ea3a0693798daeafd896d77f0b8f1fec3cc5Douglas Gregor Tok.getLocation(), CurScope, SS); 23742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor if (!Type) { 2381ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_class_name); 23942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return 0; 24042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor } 24142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 24242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Consume the identifier. 24342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor ConsumeToken(); 24442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 24542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return Type; 24642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor} 24742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 248e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or 249e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which 250e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that 251e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// cannot start a definition. 252e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 253e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-specifier: [C++ class] 254e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head '{' member-specification[opt] '}' 255e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head '{' member-specification[opt] '}' attributes[opt] 256e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head: 257e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key identifier[opt] base-clause[opt] 258e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key nested-name-specifier identifier base-clause[opt] 259e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key nested-name-specifier[opt] simple-template-id 260e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-clause[opt] 261e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] class-key attributes[opt] identifier[opt] base-clause[opt] 262e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] class-key attributes[opt] nested-name-specifier 263e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// identifier base-clause[opt] 264e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] class-key attributes[opt] nested-name-specifier[opt] 265e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// simple-template-id base-clause[opt] 266e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key: 267e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'class' 268e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'struct' 269e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'union' 270e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 271e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier: [C++ dcl.type.elab] 272e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key ::[opt] nested-name-specifier[opt] identifier 273e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key ::[opt] nested-name-specifier[opt] 'template'[opt] 274e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// simple-template-id 275e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 276e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// Note that the C++ class-specifier and elaborated-type-specifier, 277e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// together, subsume the C99 struct-or-union-specifier: 278e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 279e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union-specifier: [C99 6.7.2.1] 280e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union identifier[opt] '{' struct-contents '}' 281e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union identifier 282e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] struct-or-union attributes[opt] identifier[opt] '{' struct-contents 283e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// '}' attributes[opt] 284e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] struct-or-union attributes[opt] identifier 285e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union: 286e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'struct' 287e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'union' 288c4b4e7b8f6ca9b036824e048af49cd2a52b57cdfDouglas Gregorvoid Parser::ParseClassSpecifier(DeclSpec &DS, 289c4b4e7b8f6ca9b036824e048af49cd2a52b57cdfDouglas Gregor TemplateParameterLists *TemplateParams) { 290e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor assert((Tok.is(tok::kw_class) || 291e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Tok.is(tok::kw_struct) || 292e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Tok.is(tok::kw_union)) && 293e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor "Not a class specifier"); 294e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor DeclSpec::TST TagType = 295e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Tok.is(tok::kw_class) ? DeclSpec::TST_class : 296e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Tok.is(tok::kw_struct) ? DeclSpec::TST_struct : 297e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor DeclSpec::TST_union; 298e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 299e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation StartLoc = ConsumeToken(); 300e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 301e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor AttributeList *Attr = 0; 302e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If attributes exist after tag, parse them. 303e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw___attribute)) 304e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Attr = ParseAttributes(); 305e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 306f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff // If declspecs exist after tag, parse them. 307f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff if (Tok.is(tok::kw___declspec) && PP.getLangOptions().Microsoft) 308f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff FuzzyParseMicrosoftDeclSpec(); 309f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff 310eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Parse the (optional) nested-name-specifier. 311eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis CXXScopeSpec SS; 3127a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS)) { 313eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis if (Tok.isNot(tok::identifier)) 314eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis Diag(Tok, diag::err_expected_ident); 315eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis } 316e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 317e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the (optional) class name. 318e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // FIXME: Alternatively, parse a simple-template-id. 319e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IdentifierInfo *Name = 0; 320e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation NameLoc; 321e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::identifier)) { 322e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Name = Tok.getIdentifierInfo(); 323e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor NameLoc = ConsumeToken(); 324e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 325e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 326e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // There are three options here. If we have 'struct foo;', then 327e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // this is a forward declaration. If we have 'struct foo {...' or 328e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // 'struct fo :...' then this is a definition. Otherwise we have 329e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // something like 'struct foo xyz', a reference. 330e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Action::TagKind TK; 331e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))) 332e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor TK = Action::TK_Definition; 333e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor else if (Tok.is(tok::semi)) 334e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor TK = Action::TK_Declaration; 335e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor else 336e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor TK = Action::TK_Reference; 337e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 338e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (!Name && TK != Action::TK_Definition) { 339e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // We have a declaration or reference to an anonymous class. 3401ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(StartLoc, diag::err_anon_type_definition) 3411ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner << DeclSpec::getSpecifierName(TagType); 342e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 343e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Skip the rest of this declarator, up until the comma or semicolon. 344e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SkipUntil(tok::comma, true); 345e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor return; 346e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 347e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 348e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the tag portion of this. 349c4b4e7b8f6ca9b036824e048af49cd2a52b57cdfDouglas Gregor DeclTy *TagDecl 350c4b4e7b8f6ca9b036824e048af49cd2a52b57cdfDouglas Gregor = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS, Name, 351c4b4e7b8f6ca9b036824e048af49cd2a52b57cdfDouglas Gregor NameLoc, Attr, 352c4b4e7b8f6ca9b036824e048af49cd2a52b57cdfDouglas Gregor Action::MultiTemplateParamsArg( 353c4b4e7b8f6ca9b036824e048af49cd2a52b57cdfDouglas Gregor Actions, 354c4b4e7b8f6ca9b036824e048af49cd2a52b57cdfDouglas Gregor TemplateParams? &(*TemplateParams)[0] : 0, 355c4b4e7b8f6ca9b036824e048af49cd2a52b57cdfDouglas Gregor TemplateParams? TemplateParams->size() : 0)); 356e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 357e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the optional base clause (C++ only). 358e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (getLang().CPlusPlus && Tok.is(tok::colon)) { 359e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ParseBaseClause(TagDecl); 360e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 361e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 362e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If there is a body, parse it and inform the actions module. 363e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::l_brace)) 36407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis if (getLang().CPlusPlus) 36507952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis ParseCXXMemberSpecification(StartLoc, TagType, TagDecl); 36607952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis else 3674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ParseStructUnionBody(StartLoc, TagType, TagDecl); 368e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor else if (TK == Action::TK_Definition) { 369e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // FIXME: Complain that we have a base-specifier list but no 370e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // definition. 3711ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_lbrace); 372e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 373e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 374e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor const char *PrevSpec = 0; 375e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, TagDecl)) 3761ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec; 377e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 378e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 379e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived]. 380e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 381e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-clause : [C++ class.derived] 382e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ':' base-specifier-list 383e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier-list: 384e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier '...'[opt] 385e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier-list ',' base-specifier '...'[opt] 386e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregorvoid Parser::ParseBaseClause(DeclTy *ClassDecl) 387e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor{ 388e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor assert(Tok.is(tok::colon) && "Not a base clause"); 389e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 390e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 391f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Build up an array of parsed base specifiers. 392f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor llvm::SmallVector<BaseTy *, 8> BaseInfo; 393f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor 394e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor while (true) { 395e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse a base-specifier. 396f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor BaseResult Result = ParseBaseSpecifier(ClassDecl); 3975ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor if (Result.isInvalid()) { 398e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Skip the rest of this base specifier, up until the comma or 399e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // opening brace. 400f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor SkipUntil(tok::comma, tok::l_brace, true, true); 401f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor } else { 402f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Add this to our array of base specifiers. 4035ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor BaseInfo.push_back(Result.get()); 404e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 405e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 406e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If the next token is a comma, consume it and keep reading 407e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // base-specifiers. 408e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.isNot(tok::comma)) break; 409e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 410e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Consume the comma. 411e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 412e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 413f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor 414f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Attach the base specifiers 415f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor Actions.ActOnBaseSpecifiers(ClassDecl, &BaseInfo[0], BaseInfo.size()); 416e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 417e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 418e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is 419e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example: 420e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class foo : public bar, virtual private baz { 421e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers. 422e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 423e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier: [C++ class.derived] 424e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ::[opt] nested-name-specifier[opt] class-name 425e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt] 426e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-name 427e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt] 428e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-name 429f8268ae3196002bbab6adb830302e79b0f368f13Douglas GregorParser::BaseResult Parser::ParseBaseSpecifier(DeclTy *ClassDecl) 430e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor{ 431e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor bool IsVirtual = false; 432e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation StartLoc = Tok.getLocation(); 433e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 434e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the 'virtual' keyword. 435e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw_virtual)) { 436e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 437e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IsVirtual = true; 438e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 439e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 440e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse an (optional) access specifier. 441e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor AccessSpecifier Access = getAccessSpecifierIfPresent(); 442e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Access) 443e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 444e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 445e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the 'virtual' keyword (again!), in case it came after the 446e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // access specifier. 447e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw_virtual)) { 448e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation VirtualLoc = ConsumeToken(); 449e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (IsVirtual) { 450e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Complain about duplicate 'virtual' 4511ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(VirtualLoc, diag::err_dup_virtual) 4521ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner << SourceRange(VirtualLoc, VirtualLoc); 453e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 454e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 455e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IsVirtual = true; 456e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 457e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 458eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Parse optional '::' and optional nested-name-specifier. 459eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis CXXScopeSpec SS; 4607a0ab5f387722c83e19c7133b46b16988eb19e45Chris Lattner ParseOptionalCXXScopeSpecifier(SS); 461e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 462e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // The location of the base class itself. 463e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation BaseLoc = Tok.getLocation(); 46442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 46542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Parse the class-name. 466eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis TypeTy *BaseType = ParseClassName(&SS); 46742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor if (!BaseType) 46842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return true; 469e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 470e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Find the complete source range for the base-specifier. 471e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceRange Range(StartLoc, BaseLoc); 472e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 473e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Notify semantic analysis that we have parsed a complete 474e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // base-specifier. 475a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access, 476a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl BaseType, BaseLoc); 477e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 478e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 479e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is 480e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier. 481e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 482e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// access-specifier: [C++ class.derived] 483e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'private' 484e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'protected' 485e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public' 4861b7f89846f10681ce3cbe89ef5d60691d55bd918Douglas GregorAccessSpecifier Parser::getAccessSpecifierIfPresent() const 487e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor{ 488e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor switch (Tok.getKind()) { 489e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor default: return AS_none; 490e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_private: return AS_private; 491e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_protected: return AS_protected; 492e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_public: return AS_public; 493e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 494e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 4954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 4964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration. 4974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 4984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declaration: 4994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// decl-specifier-seq[opt] member-declarator-list[opt] ';' 5004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// function-definition ';'[opt] 5014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO] 5024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// using-declaration [TODO] 5034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// [C++0x] static_assert-declaration [TODO] 5044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// template-declaration [TODO] 505bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU] '__extension__' member-declaration 5064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 5074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator-list: 5084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator 5094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator-list ',' member-declarator 5104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 5114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator: 5124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// declarator pure-specifier[opt] 5134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// declarator constant-initializer[opt] 5144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// identifier[opt] ':' constant-expression 5154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 5164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// pure-specifier: [TODO] 5174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// '= 0' 5184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 5194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// constant-initializer: 5204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// '=' constant-expression 5214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 5224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios KyrtzidisParser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) { 523bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner // Handle: member-declaration ::= '__extension__' member-declaration 524bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner if (Tok.is(tok::kw___extension__)) { 525bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner // __extension__ silences extension warnings in the subexpression. 526bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner ExtensionRAIIObject O(Diags); // Use RAII to do this. 527bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner ConsumeToken(); 528bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner return ParseCXXClassMemberDeclaration(AS); 529bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner } 530bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner 5314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation DSStart = Tok.getLocation(); 5324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // decl-specifier-seq: 5334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the common declaration-specifiers piece. 5344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclSpec DS; 5354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ParseDeclarationSpecifiers(DS); 5364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 5374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) { 5384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 5394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // C++ 9.2p7: The member-declarator-list can be omitted only after a 5404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // class-specifier or an enum-specifier or in a friend declaration. 5414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // FIXME: Friend declarations. 5424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis switch (DS.getTypeSpecType()) { 5434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case DeclSpec::TST_struct: 5444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case DeclSpec::TST_union: 5454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case DeclSpec::TST_class: 5464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case DeclSpec::TST_enum: 5474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return Actions.ParsedFreeStandingDeclSpec(CurScope, DS); 5484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis default: 5494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Diag(DSStart, diag::err_no_declarators); 5504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return 0; 5514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 5524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 55307952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis 5544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Declarator DeclaratorInfo(DS, Declarator::MemberContext); 5554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 5563a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.isNot(tok::colon)) { 5573a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // Parse the first declarator. 5583a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 5593a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // Error parsing the declarator? 56010bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor if (!DeclaratorInfo.hasName()) { 5613a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // If so, skip until the semi-colon or a }. 5624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::r_brace, true); 5633a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.is(tok::semi)) 5643a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeToken(); 5654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return 0; 5664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 5674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 5683a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // function-definition: 5697ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.is(tok::l_brace) 5707ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor || (DeclaratorInfo.isFunctionDeclarator() && Tok.is(tok::colon))) { 5713a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (!DeclaratorInfo.isFunctionDeclarator()) { 5723a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis Diag(Tok, diag::err_func_def_no_params); 5733a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeBrace(); 5743a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis SkipUntil(tok::r_brace, true); 5753a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis return 0; 5763a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 5773a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis 5783a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 5793a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis Diag(Tok, diag::err_function_declared_typedef); 5803a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // This recovery skips the entire function body. It would be nice 5813a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // to simply call ParseCXXInlineMethodDef() below, however Sema 5823a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // assumes the declarator represents a function, not a typedef. 5833a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeBrace(); 5843a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis SkipUntil(tok::r_brace, true); 5853a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis return 0; 5863a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 5874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 5883a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis return ParseCXXInlineMethodDef(AS, DeclaratorInfo); 5893a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 5904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 5914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 5924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator-list: 5934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator 5944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator-list ',' member-declarator 5954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 5964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclTy *LastDeclInGroup = 0; 59715faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult BitfieldSize(Actions); 59815faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl OwningExprResult Init(Actions); 5994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis while (1) { 6014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator: 6034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // declarator pure-specifier[opt] 6044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // declarator constant-initializer[opt] 6054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // identifier[opt] ':' constant-expression 6064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::colon)) { 6084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 6090e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl BitfieldSize = ParseConstantExpression(); 6100e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (BitfieldSize.isInvalid()) 6114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::comma, true, true); 6124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 6134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // pure-specifier: 6154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // '= 0' 6164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // 6174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // constant-initializer: 6184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // '=' constant-expression 6194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::equal)) { 6214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 6220e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl Init = ParseInitializer(); 6230e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (Init.isInvalid()) 6244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::comma, true, true); 6254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 6264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If attributes exist after the declarator, parse them. 6284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 6294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclaratorInfo.AddAttributes(ParseAttributes()); 6304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 63107952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // NOTE: If Sema is the Action module and declarator is an instance field, 63207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // this call will *not* return the created decl; LastDeclInGroup will be 63307952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // returned instead. 63407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // See Sema::ActOnCXXMemberDeclarator for details. 6354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis LastDeclInGroup = Actions.ActOnCXXMemberDeclarator(CurScope, AS, 6364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclaratorInfo, 637effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl BitfieldSize.release(), 638effa8d1c97b00a3f53e972b0e61d9aade5ea1c57Sebastian Redl Init.release(), 6394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis LastDeclInGroup); 6404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 64172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (DeclaratorInfo.isFunctionDeclarator() && 64272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor DeclaratorInfo.getDeclSpec().getStorageClassSpec() 64372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor != DeclSpec::SCS_typedef) { 64472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // We just declared a member function. If this member function 64572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // has any default arguments, we'll need to parse them later. 64672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateParsedMethodDeclaration *LateMethod = 0; 64772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor DeclaratorChunk::FunctionTypeInfo &FTI 64872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor = DeclaratorInfo.getTypeObject(0).Fun; 64972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) { 65072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) { 65172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (!LateMethod) { 65272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Push this method onto the stack of late-parsed method 65372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // declarations. 65472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor getCurTopClassStack().MethodDecls.push_back( 65572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateParsedMethodDeclaration(LastDeclInGroup)); 65672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateMethod = &getCurTopClassStack().MethodDecls.back(); 65772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 65872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Add all of the parameters prior to this one (they don't 65972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // have default arguments). 66072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateMethod->DefaultArgs.reserve(FTI.NumArgs); 66172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor for (unsigned I = 0; I < ParamIdx; ++I) 66272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateMethod->DefaultArgs.push_back( 66372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param)); 66472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 66572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 66672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Add this parameter to the list of parameters (it or may 66772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // not have a default argument). 66872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateMethod->DefaultArgs.push_back( 66972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param, 67072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor FTI.ArgInfo[ParamIdx].DefaultArgTokens)); 67172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 67272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 67372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 67472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 6754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If we don't have a comma, it is either the end of the list (a ';') 6764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // or an error, bail out. 6774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.isNot(tok::comma)) 6784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 6794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Consume the comma. 6814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 6824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the next declarator. 6844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclaratorInfo.clear(); 68515faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl BitfieldSize = 0; 68615faa7fdfb496489dec9470aa5eb699b29ecdaccSebastian Redl Init = 0; 6874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Attributes are only allowed on the second declarator. 6894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 6904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclaratorInfo.AddAttributes(ParseAttributes()); 6914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6923a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.isNot(tok::colon)) 6933a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 6944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 6954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 6964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) { 6974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 6984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Reverse the chain list. 6994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return Actions.FinalizeDeclaratorGroup(CurScope, LastDeclInGroup); 7004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 7014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Diag(Tok, diag::err_expected_semi_decl_list); 7034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Skip to end of block or statement 7044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::r_brace, true, true); 7054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) 7064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 7074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return 0; 7084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 7094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition. 7114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 7124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-specification: 7134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declaration member-specification[opt] 7144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// access-specifier ':' member-specification[opt] 7154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 7164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidisvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, 7174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis unsigned TagType, DeclTy *TagDecl) { 71831fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta assert((TagType == DeclSpec::TST_struct || 7194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis TagType == DeclSpec::TST_union || 72031fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta TagType == DeclSpec::TST_class) && "Invalid TagType!"); 7214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation LBraceLoc = ConsumeBrace(); 7234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7243218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor if (!CurScope->isClassScope() && // Not about to define a nested class. 7254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurScope->isInCXXInlineMethodScope()) { 7264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // We will define a local class of an inline method. 7274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Push a new LexedMethodsForTopClass for its inline methods. 7284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis PushTopClassStack(); 7294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 7304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Enter a scope for the class. 7323218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope); 7334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 73472de6676bd30f9081ee4166bbe07b4c270258ce6Douglas Gregor Actions.ActOnTagStartDefinition(CurScope, TagDecl); 7354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // C++ 11p3: Members of a class defined with the keyword class are private 7374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // by default. Members of a class defined with the keywords struct or union 7384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // are public by default. 7394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AccessSpecifier CurAS; 7404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (TagType == DeclSpec::TST_class) 7414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS_private; 7424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis else 7434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS_public; 7444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // While we still have something to read, read the member-declarations. 7464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 7474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Each iteration of this loop reads one member-declaration. 7484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Check for extraneous top-level semicolon. 7504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) { 7514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Diag(Tok, diag::ext_extra_struct_semi); 7524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 7534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis continue; 7544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 7554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AccessSpecifier AS = getAccessSpecifierIfPresent(); 7574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (AS != AS_none) { 7584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Current token is a C++ access specifier. 7594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS; 7604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 7614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ExpectAndConsume(tok::colon, diag::err_expected_colon); 7624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis continue; 7634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 7644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse all the comma separated declarators. 7664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ParseCXXClassMemberDeclaration(CurAS); 7674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 7684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); 7704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AttributeList *AttrList = 0; 7724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If attributes exist after class contents, parse them. 7734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::kw___attribute)) 7744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AttrList = ParseAttributes(); // FIXME: where should I put them? 7754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Actions.ActOnFinishCXXMemberSpecification(CurScope, RecordLoc, TagDecl, 7774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis LBraceLoc, RBraceLoc); 7784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // C++ 9.2p2: Within the class member-specification, the class is regarded as 7804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // complete within function bodies, default arguments, 7814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // exception-specifications, and constructor ctor-initializers (including 7824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // such things in nested classes). 7834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // 78472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // FIXME: Only function bodies and constructor ctor-initializers are 78572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // parsed correctly, fix the rest. 7863218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor if (!CurScope->getParent()->isClassScope()) { 7874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // We are not inside a nested class. This class and its nested classes 78872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // are complete and we can parse the delayed portions of method 78972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // declarations and the lexed inline method definitions. 79072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor ParseLexedMethodDeclarations(); 7914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ParseLexedMethodDefs(); 7924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 7934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // For a local class of inline method, pop the LexedMethodsForTopClass that 7944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // was previously pushed. 7954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 79631fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta assert((CurScope->isInCXXInlineMethodScope() || 79731fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta TopClassStacks.size() == 1) && 7984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis "MethodLexers not getting popped properly!"); 7994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (CurScope->isInCXXInlineMethodScope()) 8004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis PopTopClassStack(); 8014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 8024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Leave the class scope. 8048935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ClassScope.Exit(); 8054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 80672de6676bd30f9081ee4166bbe07b4c270258ce6Douglas Gregor Actions.ActOnTagFinishDefinition(CurScope, TagDecl); 8074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 8087ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8097ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer, 8107ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a 8117ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers 8127ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below: 8137ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 8147ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code 8157ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { }; 8167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base { 8177ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// int x; 8187ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// float f; 8197ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public: 8207ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// Derived(float f) : Base(), x(17), f(f) { } 8217ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// }; 8227ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode 8237ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 8247ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] ctor-initializer: 8257ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ':' mem-initializer-list 8267ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 8277ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-list: 8287ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// mem-initializer 8297ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// mem-initializer , mem-initializer-list 8307ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregorvoid Parser::ParseConstructorInitializer(DeclTy *ConstructorDecl) { 8317ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'"); 8327ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8337ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation ColonLoc = ConsumeToken(); 8347ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor llvm::SmallVector<MemInitTy*, 4> MemInitializers; 8367ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor do { 8387ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); 8395ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor if (!MemInit.isInvalid()) 8405ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor MemInitializers.push_back(MemInit.get()); 8417ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8427ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.is(tok::comma)) 8437ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor ConsumeToken(); 8447ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor else if (Tok.is(tok::l_brace)) 8457ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor break; 8467ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor else { 8477ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Skip over garbage, until we get to '{'. Don't eat the '{'. 8487ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SkipUntil(tok::l_brace, true, true); 8497ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor break; 8507ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 8517ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } while (true); 8527ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8537ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, 8547ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor &MemInitializers[0], MemInitializers.size()); 8557ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor} 8567ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8577ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is 8587ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one 8597ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See 8607ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example. 8617ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 8627ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer: 8637ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// mem-initializer-id '(' expression-list[opt] ')' 8647ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 8657ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id: 8667ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// '::'[opt] nested-name-specifier[opt] class-name 8677ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// identifier 8687ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas GregorParser::MemInitResult Parser::ParseMemInitializer(DeclTy *ConstructorDecl) { 8697ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // FIXME: parse '::'[opt] nested-name-specifier[opt] 8707ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8717ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.isNot(tok::identifier)) { 8721ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_member_or_base_name); 8737ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor return true; 8747ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 8757ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8767ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Get the identifier. This may be a member name or a class name, 8777ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // but we'll let the semantic analysis determine which it is. 8787ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor IdentifierInfo *II = Tok.getIdentifierInfo(); 8797ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation IdLoc = ConsumeToken(); 8807ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8817ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Parse the '('. 8827ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.isNot(tok::l_paren)) { 8831ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_lparen); 8847ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor return true; 8857ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 8867ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation LParenLoc = ConsumeParen(); 8877ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8887ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Parse the optional expression-list. 889a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ExprVector ArgExprs(Actions); 8907ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor CommaLocsTy CommaLocs; 8917ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) { 8927ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SkipUntil(tok::r_paren); 8937ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor return true; 8947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 8957ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 8967ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 8977ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 898a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, II, IdLoc, 899a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl LParenLoc, ArgExprs.take(), 900a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl ArgExprs.size(), &CommaLocs[0], RParenLoc); 9017ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor} 9020fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 9030fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// ParseExceptionSpecification - Parse a C++ exception-specification 9040fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// (C++ [except.spec]). 9050fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 906a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// exception-specification: 907a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// 'throw' '(' type-id-list [opt] ')' 908a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS] 'throw' '(' '...' ')' 9090fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 910a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// type-id-list: 911a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// type-id 912a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// type-id-list ',' type-id 9130fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 9140fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregorbool Parser::ParseExceptionSpecification() { 9150fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor assert(Tok.is(tok::kw_throw) && "expected throw"); 9160fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 9170fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor SourceLocation ThrowLoc = ConsumeToken(); 9180fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 9190fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor if (!Tok.is(tok::l_paren)) { 9200fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor return Diag(Tok, diag::err_expected_lparen_after) << "throw"; 9210fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor } 9220fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor SourceLocation LParenLoc = ConsumeParen(); 9230fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 924a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor // Parse throw(...), a Microsoft extension that means "this function 925a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor // can throw anything". 926a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor if (Tok.is(tok::ellipsis)) { 927a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor SourceLocation EllipsisLoc = ConsumeToken(); 928a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor if (!getLang().Microsoft) 929a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec); 930a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 931a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor return false; 932a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor } 933a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor 9340fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor // Parse the sequence of type-ids. 9350fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor while (Tok.isNot(tok::r_paren)) { 9360fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor ParseTypeName(); 9370fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor if (Tok.is(tok::comma)) 9380fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor ConsumeToken(); 9390fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor else 9400fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor break; 9410fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor } 9420fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 9430fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 9440fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor return false; 9450fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor} 946