ParseDeclCXX.cpp revision 0eb7526cd2524af78fb9a2a2522045fb25fc3d27
18f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -----------------------===// 28f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 38f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// The LLVM Compiler Infrastructure 48f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 78f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 88f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===----------------------------------------------------------------------===// 98f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 108f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// This file implements the C++ Declaration portions of the Parser interfaces. 118f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 128f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===----------------------------------------------------------------------===// 138f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 140c6139d0c2497c4e8780340e0dc097de041f248eAnders Carlsson#include "clang/Basic/OperatorKinds.h" 151b7f89846f10681ce3cbe89ef5d60691d55bd918Douglas Gregor#include "clang/Parse/Parser.h" 16500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h" 1719510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h" 1819510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/Scope.h" 1919510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/ParsedTemplate.h" 20f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall#include "clang/Sema/PrettyDeclStackTrace.h" 218fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer#include "llvm/ADT/SmallString.h" 22d167ca0d26e43292b8b9e8d5300d92784ae0e27dChris Lattner#include "RAIIObjectsForParser.h" 238f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattnerusing namespace clang; 248f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 258f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// ParseNamespace - We know that the current token is a namespace keyword. This 26d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// may either be a top level namespace or a block-level namespace alias. If 27d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// there was an inline keyword, it has already been parsed. 288f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 298f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// namespace-definition: [C++ 7.3: basic.namespace] 308f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// named-namespace-definition 318f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// unnamed-namespace-definition 328f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 338f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// unnamed-namespace-definition: 34d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// 'inline'[opt] 'namespace' attributes[opt] '{' namespace-body '}' 358f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 368f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// named-namespace-definition: 378f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// original-namespace-definition 388f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// extension-namespace-definition 398f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 408f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// original-namespace-definition: 41d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// 'inline'[opt] 'namespace' identifier attributes[opt] 42d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// '{' namespace-body '}' 438f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 448f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// extension-namespace-definition: 45d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// 'inline'[opt] 'namespace' original-namespace-name 46d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// '{' namespace-body '}' 471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 488f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// namespace-alias-definition: [C++ 7.3.2: namespace.alias] 498f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 'namespace' identifier '=' qualified-namespace-specifier ';' 508f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 51d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespace(unsigned Context, 52d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl SourceLocation &DeclEnd, 53d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl SourceLocation InlineLoc) { 5404d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner assert(Tok.is(tok::kw_namespace) && "Not a namespace!"); 558f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'. 569735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian ObjCDeclContextSwitch ObjCDC(*this); 57a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian 5849f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor if (Tok.is(tok::code_completion)) { 5923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteNamespaceDecl(getCurScope()); 607d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 617d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return 0; 6249f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor } 63193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 648f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation IdentLoc; 658f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner IdentifierInfo *Ident = 0; 66f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<SourceLocation> ExtraIdentLoc; 67f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<IdentifierInfo*> ExtraIdent; 68f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<SourceLocation> ExtraNamespaceLoc; 696a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor 706a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor Token attrTok; 711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7204d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner if (Tok.is(tok::identifier)) { 738f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner Ident = Tok.getIdentifierInfo(); 748f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner IdentLoc = ConsumeToken(); // eat the identifier. 75f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu while (Tok.is(tok::coloncolon) && NextToken().is(tok::identifier)) { 76f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ExtraNamespaceLoc.push_back(ConsumeToken()); 77f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ExtraIdent.push_back(Tok.getIdentifierInfo()); 78f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ExtraIdentLoc.push_back(ConsumeToken()); 79f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 808f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner } 811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 828f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner // Read label attributes, if present. 830b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributes attrs(AttrFactory); 846a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor if (Tok.is(tok::kw___attribute)) { 856a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor attrTok = Tok; 867f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseGNUAttributes(attrs); 876a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor } 881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 896a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor if (Tok.is(tok::equal)) { 907f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (!attrs.empty()) 916a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor Diag(attrTok, diag::err_unexpected_namespace_attributes_alias); 92d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl if (InlineLoc.isValid()) 93d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl Diag(InlineLoc, diag::err_inline_namespace_alias) 94d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl << FixItHint::CreateRemoval(InlineLoc); 959735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd); 966a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor } 971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 98f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 994a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_brace); 1004a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.consumeOpen()) { 101f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (!ExtraIdent.empty()) { 102f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon) 103f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back()); 104f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 1051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(Tok, Ident ? diag::err_expected_lbrace : 1065144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner diag::err_expected_ident_lbrace); 107d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 1085144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner } 1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() || 11123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor getCurScope()->isInObjcMethodScope() || getCurScope()->getBlockParent() || 11223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor getCurScope()->getFnParent()) { 113f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (!ExtraIdent.empty()) { 114f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon) 115f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back()); 116f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 1174a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope); 11895f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor SkipUntil(tok::r_brace, false); 119d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 12095f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor } 12195f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor 122f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (!ExtraIdent.empty()) { 123f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu TentativeParsingAction TPA(*this); 124f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu SkipUntil(tok::r_brace, /*StopAtSemi*/false, /*DontConsume*/true); 125f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Token rBraceToken = Tok; 126f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu TPA.Revert(); 127f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 128f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (!rBraceToken.is(tok::r_brace)) { 129f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon) 130f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back()); 131f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } else { 1329910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer std::string NamespaceFix; 133f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu for (std::vector<IdentifierInfo*>::iterator I = ExtraIdent.begin(), 134f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu E = ExtraIdent.end(); I != E; ++I) { 135f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceFix += " { namespace "; 136f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceFix += (*I)->getName(); 137f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 1389910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer 139f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::string RBraces; 1409910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer for (unsigned i = 0, e = ExtraIdent.size(); i != e; ++i) 141f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu RBraces += "} "; 1429910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer 143f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon) 144f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << FixItHint::CreateReplacement(SourceRange(ExtraNamespaceLoc.front(), 145f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ExtraIdentLoc.back()), 146f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceFix) 147f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << FixItHint::CreateInsertion(rBraceToken.getLocation(), RBraces); 148f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 149f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 150f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 15188e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl // If we're still good, complain about inline namespaces in non-C++0x now. 1527fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith if (InlineLoc.isValid()) 1534e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Diag(InlineLoc, getLangOpts().CPlusPlus0x ? 1547fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_inline_namespace : diag::ext_inline_namespace); 15588e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl 1565144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner // Enter a scope for the namespace. 1575144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner ParseScope NamespaceScope(this, Scope::DeclScope); 1582d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 159d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl *NamespcDecl = 160acba90f30876b4140b738f0d3dd0e50724053a96Abramo Bagnara Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, NamespaceLoc, 1614a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor IdentLoc, Ident, T.getOpenLocation(), 1624a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor attrs.getList()); 1632d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 164f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc, 165f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall "parsing namespace"); 1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 167f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu // Parse the contents of the namespace. This includes parsing recovery on 168f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu // any improperly nested namespaces. 169f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParseInnerNamespace(ExtraIdentLoc, ExtraIdent, ExtraNamespaceLoc, 0, 1704a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor InlineLoc, attrs, T); 1711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1725144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner // Leave the namespace scope. 1735144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner NamespaceScope.Exit(); 1748ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis 1754a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor DeclEnd = T.getCloseLocation(); 1764a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Actions.ActOnFinishNamespaceDef(NamespcDecl, DeclEnd); 1772d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 1785144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner return NamespcDecl; 1798f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner} 180c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 181f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu/// ParseInnerNamespace - Parse the contents of a namespace. 182f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieuvoid Parser::ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc, 183f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<IdentifierInfo*>& Ident, 184f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<SourceLocation>& NamespaceLoc, 185f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu unsigned int index, SourceLocation& InlineLoc, 186f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParsedAttributes& attrs, 1874a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker &Tracker) { 188f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (index == Ident.size()) { 189f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 190f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParsedAttributesWithRange attrs(AttrFactory); 191f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu MaybeParseCXX0XAttributes(attrs); 192f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu MaybeParseMicrosoftAttributes(attrs); 193f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParseExternalDeclaration(attrs); 194f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 1954a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor 1964a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor // The caller is what called check -- we are simply calling 1974a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor // the close for it. 1984a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.consumeClose(); 199f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 200f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu return; 201f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 202f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 203f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu // Parse improperly nested namespaces. 204f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParseScope NamespaceScope(this, Scope::DeclScope); 205f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Decl *NamespcDecl = 206f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Actions.ActOnStartNamespaceDef(getCurScope(), SourceLocation(), 207f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceLoc[index], IdentLoc[index], 2084a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Ident[index], Tracker.getOpenLocation(), 2094a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor attrs.getList()); 210f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 211f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParseInnerNamespace(IdentLoc, Ident, NamespaceLoc, ++index, InlineLoc, 2124a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor attrs, Tracker); 213f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 214f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceScope.Exit(); 215f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 2164a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Actions.ActOnFinishNamespaceDef(NamespcDecl, Tracker.getCloseLocation()); 217f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu} 218f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 219f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// ParseNamespaceAlias - Parse the part after the '=' in a namespace 220f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// alias definition. 221f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// 222d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc, 2230b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall SourceLocation AliasLoc, 2240b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall IdentifierInfo *Alias, 2250b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall SourceLocation &DeclEnd) { 226f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson assert(Tok.is(tok::equal) && "Not equal token"); 2271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 228f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson ConsumeToken(); // eat the '='. 2291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 23049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor if (Tok.is(tok::code_completion)) { 23123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteNamespaceAliasDecl(getCurScope()); 2327d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 2337d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return 0; 23449f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor } 235193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 236f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson CXXScopeSpec SS; 237f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson // Parse (optional) nested-name-specifier. 238efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 239f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson 240f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson if (SS.isInvalid() || Tok.isNot(tok::identifier)) { 241f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson Diag(Tok, diag::err_expected_namespace_name); 242f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson // Skip to end of the definition and eat the ';'. 243f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson SkipUntil(tok::semi); 244d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 245f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson } 246f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson 247f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson // Parse identifier. 24803bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson IdentifierInfo *Ident = Tok.getIdentifierInfo(); 24903bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson SourceLocation IdentLoc = ConsumeToken(); 2501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 251f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson // Eat the ';'. 25297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner DeclEnd = Tok.getLocation(); 2536869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name, 2546869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner "", tok::semi); 2551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 25623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc, Alias, 25703bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson SS, IdentLoc, Ident); 258f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson} 259f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson 260c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal 261c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen. 262c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 263c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// linkage-specification: [C++ 7.5p2: dcl.link] 264c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 'extern' string-literal '{' declaration-seq[opt] '}' 265c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 'extern' string-literal declaration 266c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 2677d64271b162eaf5cae264ff64465b28af623dc17Chris LattnerDecl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) { 268c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor assert(Tok.is(tok::string_literal) && "Not a string literal!"); 269f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<8> LangBuffer; 270453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor bool Invalid = false; 2715f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid); 272453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor if (Invalid) 273d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 274c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 27599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith // FIXME: This is incorrect: linkage-specifiers are parsed in translation 27699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith // phase 7, so string-literal concatenation is supposed to occur. 27799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith // extern "" "C" "" "+" "+" { } is legal. 27899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith if (Tok.hasUDSuffix()) 27999831e4677a7e2e051af636221694d60ba31fcdbRichard Smith Diag(Tok, diag::err_invalid_string_udl); 280c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner SourceLocation Loc = ConsumeStringToken(); 281c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 282074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor ParseScope LinkageScope(this, Scope::DeclScope); 283d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl *LinkageSpec 28423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnStartLinkageSpecification(getCurScope(), 285a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara DS.getSourceRange().getBegin(), 286d56638180014e60538cd666cd11fde6d4698e051Benjamin Kramer Loc, Lang, 287a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara Tok.is(tok::l_brace) ? Tok.getLocation() 288074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor : SourceLocation()); 289074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor 2900b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributesWithRange attrs(AttrFactory); 2917f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseCXX0XAttributes(attrs); 2927f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseMicrosoftAttributes(attrs); 293193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 294074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor if (Tok.isNot(tok::l_brace)) { 295f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara // Reset the source range in DS, as the leading "extern" 296f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara // does not really belong to the inner declaration ... 297f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara DS.SetRangeStart(SourceLocation()); 298f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara DS.SetRangeEnd(SourceLocation()); 299f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara // ... but anyway remember that such an "extern" was seen. 30035f9a196ef897b9559de25aaecd957208f0b4f59Abramo Bagnara DS.setExternInLinkageSpec(true); 3017f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseExternalDeclaration(attrs, &DS); 30223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec, 303074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor SourceLocation()); 3041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 305f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor 30663a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor DS.abort(); 30763a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor 3087f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ProhibitAttributes(attrs); 309bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 3104a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_brace); 3114a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 312f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 3130b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributesWithRange attrs(AttrFactory); 3147f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseCXX0XAttributes(attrs); 3157f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseMicrosoftAttributes(attrs); 3167f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseExternalDeclaration(attrs); 317f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor } 318c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 3194a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 3207d64271b162eaf5cae264ff64465b28af623dc17Chris Lattner return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec, 3214a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 322c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner} 323e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 324f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or 325f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'. 326d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context, 32778b810559d89e996e00684335407443936ce34a1John McCall const ParsedTemplateInfo &TemplateInfo, 32878b810559d89e996e00684335407443936ce34a1John McCall SourceLocation &DeclEnd, 329c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith ParsedAttributesWithRange &attrs, 330c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith Decl **OwnedType) { 331f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(Tok.is(tok::kw_using) && "Not using token"); 3329735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian ObjCDeclContextSwitch ObjCDC(*this); 3339735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian 334f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Eat 'using'. 335f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation UsingLoc = ConsumeToken(); 336f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 33749f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor if (Tok.is(tok::code_completion)) { 33823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteUsing(getCurScope()); 3397d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 3407d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return 0; 34149f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor } 342193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 34378b810559d89e996e00684335407443936ce34a1John McCall // 'using namespace' means this is a using-directive. 34478b810559d89e996e00684335407443936ce34a1John McCall if (Tok.is(tok::kw_namespace)) { 34578b810559d89e996e00684335407443936ce34a1John McCall // Template parameters are always an error here. 34678b810559d89e996e00684335407443936ce34a1John McCall if (TemplateInfo.Kind) { 34778b810559d89e996e00684335407443936ce34a1John McCall SourceRange R = TemplateInfo.getSourceRange(); 34878b810559d89e996e00684335407443936ce34a1John McCall Diag(UsingLoc, diag::err_templated_using_directive) 34978b810559d89e996e00684335407443936ce34a1John McCall << R << FixItHint::CreateRemoval(R); 35078b810559d89e996e00684335407443936ce34a1John McCall } 35178b810559d89e996e00684335407443936ce34a1John McCall 3529735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs); 35378b810559d89e996e00684335407443936ce34a1John McCall } 354bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 355162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Otherwise, it must be a using-declaration or an alias-declaration. 35678b810559d89e996e00684335407443936ce34a1John McCall 35778b810559d89e996e00684335407443936ce34a1John McCall // Using declarations can't have attributes. 3587f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ProhibitAttributes(attrs); 3592f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner 3609735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd, 361a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian AS_none, OwnedType); 362f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 363f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 364f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes 365f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed. 366f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 367f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive: [C++ 7.3.p4: namespace.udir] 368f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'namespace' ::[opt] nested-name-specifier[opt] 369f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// namespace-name ; 370f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive: 371f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'namespace' ::[opt] nested-name-specifier[opt] 372f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// namespace-name attributes[opt] ; 373f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 374d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirective(unsigned Context, 37578b810559d89e996e00684335407443936ce34a1John McCall SourceLocation UsingLoc, 37678b810559d89e996e00684335407443936ce34a1John McCall SourceLocation &DeclEnd, 3777f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParsedAttributes &attrs) { 378f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token"); 379f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 380f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Eat 'namespace'. 381f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation NamespcLoc = ConsumeToken(); 382f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 38349f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor if (Tok.is(tok::code_completion)) { 38423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteUsingDirective(getCurScope()); 3857d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 3867d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return 0; 38749f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor } 388193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 389f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor CXXScopeSpec SS; 390f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Parse (optional) nested-name-specifier. 391efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 392f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 393f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor IdentifierInfo *NamespcName = 0; 394f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation IdentLoc = SourceLocation(); 395f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 396f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Parse namespace-name. 397823c44e6d73141f642e207980b4021ddcf09897bChris Lattner if (SS.isInvalid() || Tok.isNot(tok::identifier)) { 398f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor Diag(Tok, diag::err_expected_namespace_name); 399f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // If there was invalid namespace name, skip to end of decl, and eat ';'. 400f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SkipUntil(tok::semi); 401f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // FIXME: Are there cases, when we would like to call ActOnUsingDirective? 402d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 403f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor } 4041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 405823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Parse identifier. 406823c44e6d73141f642e207980b4021ddcf09897bChris Lattner NamespcName = Tok.getIdentifierInfo(); 407823c44e6d73141f642e207980b4021ddcf09897bChris Lattner IdentLoc = ConsumeToken(); 4081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 409823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Parse (optional) attributes (most likely GNU strong-using extension). 410bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt bool GNUAttr = false; 411bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.is(tok::kw___attribute)) { 412bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt GNUAttr = true; 4137f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseGNUAttributes(attrs); 414bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 4151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 416823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Eat ';'. 41797144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner DeclEnd = Tok.getLocation(); 4186869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner ExpectAndConsume(tok::semi, 4199ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor GNUAttr ? diag::err_expected_semi_after_attribute_list 4209ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor : diag::err_expected_semi_after_namespace_name, 4219ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor "", tok::semi); 422f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 42323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS, 4247f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall IdentLoc, NamespcName, attrs.getList()); 425f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 426f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 427162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration. 428162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// Assumes that 'using' was already seen. 429f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 430f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-declaration: [C++ 7.3.p3: namespace.udecl] 431f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'typename'[opt] ::[opt] nested-name-specifier 4329cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor/// unqualified-id 4339cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor/// 'using' :: unqualified-id 434f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 435162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// alias-declaration: C++0x [decl.typedef]p2 436162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// 'using' identifier = type-id ; 437162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// 438d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDeclaration(unsigned Context, 43978b810559d89e996e00684335407443936ce34a1John McCall const ParsedTemplateInfo &TemplateInfo, 44078b810559d89e996e00684335407443936ce34a1John McCall SourceLocation UsingLoc, 44178b810559d89e996e00684335407443936ce34a1John McCall SourceLocation &DeclEnd, 442c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith AccessSpecifier AS, 443c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith Decl **OwnedType) { 4449cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor CXXScopeSpec SS; 4457ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall SourceLocation TypenameLoc; 4469cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor bool IsTypeName; 4479cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 4489cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Ignore optional 'typename'. 44912c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor // FIXME: This is wrong; we should parse this as a typename-specifier. 4509cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (Tok.is(tok::kw_typename)) { 4517ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall TypenameLoc = Tok.getLocation(); 4529cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor ConsumeToken(); 4539cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor IsTypeName = true; 4549cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 4559cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor else 4569cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor IsTypeName = false; 4579cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 4589cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Parse nested-name-specifier. 459efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 4609cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 4619cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Check nested-name specifier. 4629cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (SS.isInvalid()) { 4639cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SkipUntil(tok::semi); 464d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 4659cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 4661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 467193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // Parse the unqualified-id. We allow parsing of both constructor and 46812c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor // destructor names and allow the action module to diagnose any semantic 46912c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor // errors. 470e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara SourceLocation TemplateKWLoc; 47112c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor UnqualifiedId Name; 472193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam if (ParseUnqualifiedId(SS, 47312c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor /*EnteringContext=*/false, 47412c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor /*AllowDestructorName=*/true, 475193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam /*AllowConstructorName=*/true, 476b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType(), 477e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara TemplateKWLoc, 47812c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor Name)) { 4799cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SkipUntil(tok::semi); 480d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 4819cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 482193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 4830b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributes attrs(AttrFactory); 484162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 485162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Maybe this is an alias-declaration. 486162e1c1b487352434552147967c3dd296ebee2f7Richard Smith bool IsAliasDecl = Tok.is(tok::equal); 487162e1c1b487352434552147967c3dd296ebee2f7Richard Smith TypeResult TypeAlias; 488162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (IsAliasDecl) { 4893e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // TODO: Attribute support. C++0x attributes may appear before the equals. 4903e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // Where can GNU attributes appear? 491162e1c1b487352434552147967c3dd296ebee2f7Richard Smith ConsumeToken(); 492162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 4934e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Diag(Tok.getLocation(), getLangOpts().CPlusPlus0x ? 4947fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_alias_declaration : 4957fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::ext_alias_declaration); 496162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 4973e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // Type alias templates cannot be specialized. 4983e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith int SpecKind = -1; 499536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith if (TemplateInfo.Kind == ParsedTemplateInfo::Template && 500536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith Name.getKind() == UnqualifiedId::IK_TemplateId) 5013e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SpecKind = 0; 5023e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization) 5033e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SpecKind = 1; 5043e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) 5053e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SpecKind = 2; 5063e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (SpecKind != -1) { 5073e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SourceRange Range; 5083e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (SpecKind == 0) 5093e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Range = SourceRange(Name.TemplateId->LAngleLoc, 5103e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Name.TemplateId->RAngleLoc); 5113e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith else 5123e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Range = TemplateInfo.getSourceRange(); 5133e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Diag(Range.getBegin(), diag::err_alias_declaration_specialization) 5143e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith << SpecKind << Range; 5153e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SkipUntil(tok::semi); 5163e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return 0; 5173e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 5183e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith 519162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Name must be an identifier. 520162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (Name.getKind() != UnqualifiedId::IK_Identifier) { 521162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Diag(Name.StartLocation, diag::err_alias_declaration_not_identifier); 522162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // No removal fixit: can't recover from this. 523162e1c1b487352434552147967c3dd296ebee2f7Richard Smith SkipUntil(tok::semi); 524162e1c1b487352434552147967c3dd296ebee2f7Richard Smith return 0; 525162e1c1b487352434552147967c3dd296ebee2f7Richard Smith } else if (IsTypeName) 526162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Diag(TypenameLoc, diag::err_alias_declaration_not_identifier) 527162e1c1b487352434552147967c3dd296ebee2f7Richard Smith << FixItHint::CreateRemoval(SourceRange(TypenameLoc, 528162e1c1b487352434552147967c3dd296ebee2f7Richard Smith SS.isNotEmpty() ? SS.getEndLoc() : TypenameLoc)); 529162e1c1b487352434552147967c3dd296ebee2f7Richard Smith else if (SS.isNotEmpty()) 530162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier) 531162e1c1b487352434552147967c3dd296ebee2f7Richard Smith << FixItHint::CreateRemoval(SS.getRange()); 532162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 5333e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TypeAlias = ParseTypeName(0, TemplateInfo.Kind ? 5343e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Declarator::AliasTemplateContext : 535cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall Declarator::AliasDeclContext, AS, OwnedType); 536162e1c1b487352434552147967c3dd296ebee2f7Richard Smith } else 537162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Parse (optional) attributes (most likely GNU strong-using extension). 538162e1c1b487352434552147967c3dd296ebee2f7Richard Smith MaybeParseGNUAttributes(attrs); 5391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5409cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Eat ';'. 5419cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor DeclEnd = Tok.getLocation(); 5429cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor ExpectAndConsume(tok::semi, diag::err_expected_semi_after, 543162e1c1b487352434552147967c3dd296ebee2f7Richard Smith !attrs.empty() ? "attributes list" : 544162e1c1b487352434552147967c3dd296ebee2f7Richard Smith IsAliasDecl ? "alias declaration" : "using declaration", 54512c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor tok::semi); 5469cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 54778b810559d89e996e00684335407443936ce34a1John McCall // Diagnose an attempt to declare a templated using-declaration. 5483e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // In C++0x, alias-declarations can be templates: 549162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // template <...> using id = type; 5503e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (TemplateInfo.Kind && !IsAliasDecl) { 55178b810559d89e996e00684335407443936ce34a1John McCall SourceRange R = TemplateInfo.getSourceRange(); 55278b810559d89e996e00684335407443936ce34a1John McCall Diag(UsingLoc, diag::err_templated_using_declaration) 55378b810559d89e996e00684335407443936ce34a1John McCall << R << FixItHint::CreateRemoval(R); 55478b810559d89e996e00684335407443936ce34a1John McCall 55578b810559d89e996e00684335407443936ce34a1John McCall // Unfortunately, we have to bail out instead of recovering by 55678b810559d89e996e00684335407443936ce34a1John McCall // ignoring the parameters, just in case the nested name specifier 55778b810559d89e996e00684335407443936ce34a1John McCall // depends on the parameters. 55878b810559d89e996e00684335407443936ce34a1John McCall return 0; 55978b810559d89e996e00684335407443936ce34a1John McCall } 56078b810559d89e996e00684335407443936ce34a1John McCall 561480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor // "typename" keyword is allowed for identifiers only, 562480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor // because it may be a type definition. 563480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor if (IsTypeName && Name.getKind() != UnqualifiedId::IK_Identifier) { 564480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor Diag(Name.getSourceRange().getBegin(), diag::err_typename_identifiers_only) 565480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor << FixItHint::CreateRemoval(SourceRange(TypenameLoc)); 566480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor // Proceed parsing, but reset the IsTypeName flag. 567480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor IsTypeName = false; 568480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor } 569480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor 5703e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (IsAliasDecl) { 5713e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams; 5723e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith MultiTemplateParamsArg TemplateParamsArg(Actions, 5733e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TemplateParams ? TemplateParams->data() : 0, 5743e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TemplateParams ? TemplateParams->size() : 0); 5753e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg, 5763e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith UsingLoc, Name, TypeAlias); 5773e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 578162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 5798113ecfa4e41e2c888b1794389dfe3bce6386493Ted Kremenek return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS, 5807f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall Name, attrs.getList(), 5817f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall IsTypeName, TypenameLoc); 582f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 583f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 584ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer/// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration. 585511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// 586c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// [C++0x] static_assert-declaration: 587c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// static_assert ( constant-expression , string-literal ) ; 588c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// 589ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer/// [C11] static_assert-declaration: 590c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// _Static_assert ( constant-expression , string-literal ) ; 591511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// 592d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){ 593c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne assert((Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) && 594c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne "Not a static_assert declaration"); 595c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne 5964e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11) 597ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer Diag(Tok, diag::ext_c11_static_assert); 598841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith if (Tok.is(tok::kw_static_assert)) 599841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith Diag(Tok, diag::warn_cxx98_compat_static_assert); 600c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne 601511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson SourceLocation StaticAssertLoc = ConsumeToken(); 6021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6034a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 6044a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.consumeOpen()) { 605511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson Diag(Tok, diag::err_expected_lparen); 606d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 607511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 6081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 60960d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AssertExpr(ParseConstantExpression()); 610511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson if (AssertExpr.isInvalid()) { 611511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson SkipUntil(tok::semi); 612d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 613511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 6141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 615ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi)) 616d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 617ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson 6180cc323c6bed7206f9743a9775ec8d9cb90655f9cRichard Smith if (!isTokenStringLiteral()) { 619511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson Diag(Tok, diag::err_expected_string_literal); 620511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson SkipUntil(tok::semi); 621d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 622511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 6231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 62460d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AssertMessage(ParseStringLiteralExpression()); 62599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith if (AssertMessage.isInvalid()) { 62699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith SkipUntil(tok::semi); 627d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 62899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith } 629511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 6304a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 6311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 63297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner DeclEnd = Tok.getLocation(); 6339ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert); 634511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 6359ae2f076ca5ab1feb3ba95629099ec2319833701John McCall return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, 6369ae2f076ca5ab1feb3ba95629099ec2319833701John McCall AssertExpr.take(), 637a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara AssertMessage.take(), 6384a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 639511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson} 640511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 6416fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// ParseDecltypeSpecifier - Parse a C++0x decltype specifier. 6426fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 6436fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 'decltype' ( expression ) 6446fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 64542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid BlaikieSourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) { 64642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie assert((Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) 64742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie && "Not a decltype specifier"); 64842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 6496fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson 65042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie ExprResult Result; 65142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation StartLoc = Tok.getLocation(); 65242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation EndLoc; 6531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 65442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Tok.is(tok::annot_decltype)) { 65542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Result = getExprAnnotation(Tok); 65642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie EndLoc = Tok.getAnnotationEndLoc(); 65742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie ConsumeToken(); 65842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Result.isInvalid()) { 65942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 66042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return EndLoc; 66142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 66242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } else { 663c7b5543ad32a5c265c02e71b2a6f9856440ed13fRichard Smith if (Tok.getIdentifierInfo()->isStr("decltype")) 664c7b5543ad32a5c265c02e71b2a6f9856440ed13fRichard Smith Diag(Tok, diag::warn_cxx98_compat_decltype); 66539304fad1c8a7b7e64121e9ae544b18e460b682cRichard Smith 66642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie ConsumeToken(); 6671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 66842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie BalancedDelimiterTracker T(*this, tok::l_paren); 66942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (T.expectAndConsume(diag::err_expected_lparen_after, 67042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie "decltype", tok::r_paren)) { 67142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 67242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return T.getOpenLocation() == Tok.getLocation() ? 67342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie StartLoc : T.getOpenLocation(); 67442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 6751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 67642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // Parse the expression 67742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 67842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // C++0x [dcl.type.simple]p4: 67942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // The operand of the decltype specifier is an unevaluated operand. 68076f3f69db1416425070177243e9f390122c553e0Richard Smith EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, 68176f3f69db1416425070177243e9f390122c553e0Richard Smith 0, /*IsDecltype=*/true); 68242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Result = ParseExpression(); 68342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Result.isInvalid()) { 684d8e4daca4a44d25a9c09d51def9e3d485d4f302cRichard Smith SkipUntil(tok::r_paren); 68542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 686d8e4daca4a44d25a9c09d51def9e3d485d4f302cRichard Smith return StartLoc; 68742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 68842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 68942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // Match the ')' 69042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie T.consumeClose(); 69142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (T.getCloseLocation().isInvalid()) { 69242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 69342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // FIXME: this should return the location of the last token 69442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // that was consumed (by "consumeClose()") 69542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return T.getCloseLocation(); 69642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 69742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 69876f3f69db1416425070177243e9f390122c553e0Richard Smith Result = Actions.ActOnDecltypeExpression(Result.take()); 69976f3f69db1416425070177243e9f390122c553e0Richard Smith if (Result.isInvalid()) { 70076f3f69db1416425070177243e9f390122c553e0Richard Smith DS.SetTypeSpecError(); 70176f3f69db1416425070177243e9f390122c553e0Richard Smith return T.getCloseLocation(); 70276f3f69db1416425070177243e9f390122c553e0Richard Smith } 70376f3f69db1416425070177243e9f390122c553e0Richard Smith 70442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie EndLoc = T.getCloseLocation(); 70542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 7066fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson 7076fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson const char *PrevSpec = 0; 708fec54013fcd0eb72642741584ca04c1bc292bef8John McCall unsigned DiagID; 7096fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson // Check for duplicate type specifiers (e.g. "int decltype(a)"). 7101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec, 71142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DiagID, Result.release())) { 712fec54013fcd0eb72642741584ca04c1bc292bef8John McCall Diag(StartLoc, DiagID) << PrevSpec; 71342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 71442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 71542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return EndLoc; 71642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie} 71742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 71842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikievoid Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec& DS, 71942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation StartLoc, 72042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation EndLoc) { 72142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // make sure we have a token we can turn into an annotation token 72242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (PP.isBacktrackEnabled()) 72342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie PP.RevertCachedTokens(1); 72442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie else 72542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie PP.EnterToken(Tok); 72642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 72742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Tok.setKind(tok::annot_decltype); 72842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie setExprAnnotation(Tok, DS.getTypeSpecType() == TST_decltype ? 72942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.getRepAsExpr() : ExprResult()); 73042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Tok.setAnnotationEndLoc(EndLoc); 73142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Tok.setLocation(StartLoc); 73242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie PP.AnnotateCachedTokens(Tok); 7336fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson} 7346fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson 735db5d44b775c60166074acd184ca9f1981c10c2a7Sean Huntvoid Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) { 736db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt assert(Tok.is(tok::kw___underlying_type) && 737db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt "Not an underlying type specifier"); 738db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 739db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt SourceLocation StartLoc = ConsumeToken(); 7404a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 7414a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen_after, 7424a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor "__underlying_type", tok::r_paren)) { 743db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt return; 744db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt } 745db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 746db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt TypeResult Result = ParseTypeName(); 747db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt if (Result.isInvalid()) { 748db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt SkipUntil(tok::r_paren); 749db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt return; 750db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt } 751db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 752db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt // Match the ')' 7534a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 7544a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.getCloseLocation().isInvalid()) 755db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt return; 756db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 757db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt const char *PrevSpec = 0; 758db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt unsigned DiagID; 759ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec, 760db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt DiagID, Result.release())) 761db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt Diag(StartLoc, DiagID) << PrevSpec; 762db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt} 763db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 76409048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// ParseBaseTypeSpecifier - Parse a C++ base-type-specifier which is either a 76509048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class name or decltype-specifier. Note that we only check that the result 76609048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// names a type; semantic analysis will need to verify that the type names a 76709048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class. The result is either a type or null, depending on whether a type 76809048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// name was found. 76942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// 77009048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// base-type-specifier: [C++ 10.1] 77109048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class-or-decltype 77209048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class-or-decltype: [C++ 10.1] 77309048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// nested-name-specifier[opt] class-name 77409048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// decltype-specifier 77542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// class-name: [C++ 9.1] 77642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// identifier 7777f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor/// simple-template-id 7781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 77922216eb4fb0936d2488fc03abd285d135c36ff01David BlaikieParser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc, 78022216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie SourceLocation &EndLocation) { 7817fe3878a36750515fb9772414ecb2489cf149d19David Blaikie // Ignore attempts to use typename 7827fe3878a36750515fb9772414ecb2489cf149d19David Blaikie if (Tok.is(tok::kw_typename)) { 7837fe3878a36750515fb9772414ecb2489cf149d19David Blaikie Diag(Tok, diag::err_expected_class_name_not_template) 7847fe3878a36750515fb9772414ecb2489cf149d19David Blaikie << FixItHint::CreateRemoval(Tok.getLocation()); 7857fe3878a36750515fb9772414ecb2489cf149d19David Blaikie ConsumeToken(); 7867fe3878a36750515fb9772414ecb2489cf149d19David Blaikie } 7877fe3878a36750515fb9772414ecb2489cf149d19David Blaikie 788152aa4b87633754801598ee282e1a17c3ec49257David Blaikie // Parse optional nested-name-specifier 789152aa4b87633754801598ee282e1a17c3ec49257David Blaikie CXXScopeSpec SS; 790152aa4b87633754801598ee282e1a17c3ec49257David Blaikie ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 791152aa4b87633754801598ee282e1a17c3ec49257David Blaikie 792152aa4b87633754801598ee282e1a17c3ec49257David Blaikie BaseLoc = Tok.getLocation(); 793152aa4b87633754801598ee282e1a17c3ec49257David Blaikie 79422216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie // Parse decltype-specifier 79542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // tok == kw_decltype is just error recovery, it can only happen when SS 79642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // isn't empty 79742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) { 798152aa4b87633754801598ee282e1a17c3ec49257David Blaikie if (SS.isNotEmpty()) 799152aa4b87633754801598ee282e1a17c3ec49257David Blaikie Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype) 800152aa4b87633754801598ee282e1a17c3ec49257David Blaikie << FixItHint::CreateRemoval(SS.getRange()); 80122216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie // Fake up a Declarator to use with ActOnTypeName. 80222216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie DeclSpec DS(AttrFactory); 80322216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie 804b57775709666e50cd925f9fc589d0fd895fc79a6David Blaikie EndLocation = ParseDecltypeSpecifier(DS); 80522216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie 80622216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 80722216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 80822216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie } 80922216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie 8107f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor // Check whether we have a template-id that names a type. 8117f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor if (Tok.is(tok::annot_template_id)) { 81225a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 813d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor if (TemplateId->Kind == TNK_Type_template || 814d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor TemplateId->Kind == TNK_Dependent_template_name) { 815059101f922de6eb765601459925f4c8914420b23Douglas Gregor AnnotateTemplateIdTokenAsType(); 8167f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 8177f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); 818b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType Type = getTypeAnnotation(Tok); 8197f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor EndLocation = Tok.getAnnotationEndLoc(); 8207f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor ConsumeToken(); 82131a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor 82231a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor if (Type) 82331a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return Type; 82431a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return true; 8257f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor } 8267f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 8277f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor // Fall through to produce an error below. 8287f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor } 8297f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 83042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor if (Tok.isNot(tok::identifier)) { 8311ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_class_name); 83231a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return true; 83342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor } 83442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 83584d0a19828599e8623223632d59447fd498999cfDouglas Gregor IdentifierInfo *Id = Tok.getIdentifierInfo(); 83684d0a19828599e8623223632d59447fd498999cfDouglas Gregor SourceLocation IdLoc = ConsumeToken(); 83784d0a19828599e8623223632d59447fd498999cfDouglas Gregor 83884d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (Tok.is(tok::less)) { 83984d0a19828599e8623223632d59447fd498999cfDouglas Gregor // It looks the user intended to write a template-id here, but the 84084d0a19828599e8623223632d59447fd498999cfDouglas Gregor // template-name was wrong. Try to fix that. 84184d0a19828599e8623223632d59447fd498999cfDouglas Gregor TemplateNameKind TNK = TNK_Type_template; 84284d0a19828599e8623223632d59447fd498999cfDouglas Gregor TemplateTy Template; 84323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(), 844059101f922de6eb765601459925f4c8914420b23Douglas Gregor &SS, Template, TNK)) { 84584d0a19828599e8623223632d59447fd498999cfDouglas Gregor Diag(IdLoc, diag::err_unknown_template_name) 84684d0a19828599e8623223632d59447fd498999cfDouglas Gregor << Id; 84784d0a19828599e8623223632d59447fd498999cfDouglas Gregor } 848193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 84984d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (!Template) 85084d0a19828599e8623223632d59447fd498999cfDouglas Gregor return true; 85184d0a19828599e8623223632d59447fd498999cfDouglas Gregor 852193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // Form the template name 85384d0a19828599e8623223632d59447fd498999cfDouglas Gregor UnqualifiedId TemplateName; 85484d0a19828599e8623223632d59447fd498999cfDouglas Gregor TemplateName.setIdentifier(Id, IdLoc); 855193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 85684d0a19828599e8623223632d59447fd498999cfDouglas Gregor // Parse the full template-id, then turn it into a type. 857e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), 858e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara TemplateName, true)) 85984d0a19828599e8623223632d59447fd498999cfDouglas Gregor return true; 86084d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (TNK == TNK_Dependent_template_name) 861059101f922de6eb765601459925f4c8914420b23Douglas Gregor AnnotateTemplateIdTokenAsType(); 862193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 86384d0a19828599e8623223632d59447fd498999cfDouglas Gregor // If we didn't end up with a typename token, there's nothing more we 86484d0a19828599e8623223632d59447fd498999cfDouglas Gregor // can do. 86584d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (Tok.isNot(tok::annot_typename)) 86684d0a19828599e8623223632d59447fd498999cfDouglas Gregor return true; 867193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 86884d0a19828599e8623223632d59447fd498999cfDouglas Gregor // Retrieve the type from the annotation token, consume that token, and 86984d0a19828599e8623223632d59447fd498999cfDouglas Gregor // return. 87084d0a19828599e8623223632d59447fd498999cfDouglas Gregor EndLocation = Tok.getAnnotationEndLoc(); 871b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType Type = getTypeAnnotation(Tok); 87284d0a19828599e8623223632d59447fd498999cfDouglas Gregor ConsumeToken(); 87384d0a19828599e8623223632d59447fd498999cfDouglas Gregor return Type; 87484d0a19828599e8623223632d59447fd498999cfDouglas Gregor } 87584d0a19828599e8623223632d59447fd498999cfDouglas Gregor 87642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // We have an identifier; check whether it is actually a type. 877059101f922de6eb765601459925f4c8914420b23Douglas Gregor ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true, 8789e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor false, ParsedType(), 879fad03b75e0297546c5d12ec420b5b79d5b7baa2aAbramo Bagnara /*IsCtorOrDtorName=*/false, 8809e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor /*NonTrivialTypeSourceInfo=*/true); 881193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam if (!Type) { 882124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor Diag(IdLoc, diag::err_expected_class_name); 88331a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return true; 88442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor } 88542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 88642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Consume the identifier. 88784d0a19828599e8623223632d59447fd498999cfDouglas Gregor EndLocation = IdLoc; 8885606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky 8895606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky // Fake up a Declarator to use with ActOnTypeName. 8900b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall DeclSpec DS(AttrFactory); 8915606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky DS.SetRangeStart(IdLoc); 8925606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky DS.SetRangeEnd(EndLocation); 893059101f922de6eb765601459925f4c8914420b23Douglas Gregor DS.getTypeSpecScope() = SS; 8945606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky 8955606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky const char *PrevSpec = 0; 8965606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky unsigned DiagID; 8975606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type); 8985606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky 8995606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 9005606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 90142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor} 90242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 903e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or 904e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which 905e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that 90669730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith/// cannot start a definition. 907e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 908e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-specifier: [C++ class] 909e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head '{' member-specification[opt] '}' 910e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head '{' member-specification[opt] '}' attributes[opt] 911e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head: 912e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key identifier[opt] base-clause[opt] 913e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key nested-name-specifier identifier base-clause[opt] 914e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key nested-name-specifier[opt] simple-template-id 915e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-clause[opt] 916e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] class-key attributes[opt] identifier[opt] base-clause[opt] 9171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU] class-key attributes[opt] nested-name-specifier 918e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// identifier base-clause[opt] 9191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU] class-key attributes[opt] nested-name-specifier[opt] 920e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// simple-template-id base-clause[opt] 921e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key: 922e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'class' 923e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'struct' 924e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'union' 925e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 926e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier: [C++ dcl.type.elab] 9271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// class-key ::[opt] nested-name-specifier[opt] identifier 9281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// class-key ::[opt] nested-name-specifier[opt] 'template'[opt] 9291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// simple-template-id 930e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 931e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// Note that the C++ class-specifier and elaborated-type-specifier, 932e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// together, subsume the C99 struct-or-union-specifier: 933e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 934e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union-specifier: [C99 6.7.2.1] 935e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union identifier[opt] '{' struct-contents '}' 936e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union identifier 937e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] struct-or-union attributes[opt] identifier[opt] '{' struct-contents 938e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// '}' attributes[opt] 939e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] struct-or-union attributes[opt] identifier 940e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union: 941e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'struct' 942e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'union' 9434c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattnervoid Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, 9444c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner SourceLocation StartLoc, DeclSpec &DS, 9454d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor const ParsedTemplateInfo &TemplateInfo, 946efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor AccessSpecifier AS, 94769730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith bool EnteringContext, DeclSpecContext DSC) { 9484c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner DeclSpec::TST TagType; 9494c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner if (TagTokKind == tok::kw_struct) 9504c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner TagType = DeclSpec::TST_struct; 9514c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner else if (TagTokKind == tok::kw_class) 9524c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner TagType = DeclSpec::TST_class; 9534c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner else { 9544c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner assert(TagTokKind == tok::kw_union && "Not a class specifier"); 9554c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner TagType = DeclSpec::TST_union; 9564c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner } 957e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 958374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor if (Tok.is(tok::code_completion)) { 959374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor // Code completion for a struct, class, or union name. 96023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteTag(getCurScope(), TagType); 9617d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return cutOffParsing(); 962374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor } 963193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 964926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // C++03 [temp.explicit] 14.7.2/8: 965926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // The usual access checking rules do not apply to names used to specify 966926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // explicit instantiations. 967926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // 968926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // As an extension we do not perform access checking on the names used to 969926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // specify explicit specializations either. This is important to allow 970926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // specializing traits classes for private types. 9711af83c444e5a2f6f50a6e1c15e6ebc618ae18a5fRichard Smith Sema::SuppressAccessChecksRAII SuppressAccess(Actions, 9721af83c444e5a2f6f50a6e1c15e6ebc618ae18a5fRichard Smith TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation || 9731af83c444e5a2f6f50a6e1c15e6ebc618ae18a5fRichard Smith TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization); 974926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth 9750b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributes attrs(AttrFactory); 976e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If attributes exist after tag, parse them. 977e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw___attribute)) 9787f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseGNUAttributes(attrs); 979e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 980f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff // If declspecs exist after tag, parse them. 981b1d397c23e1f8fd8b404d5731d531e7500f7140dJohn McCall while (Tok.is(tok::kw___declspec)) 9827f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseMicrosoftDeclSpec(attrs); 983193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 984bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // If C++0x attributes exist here, parse them. 985bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Are we consistent with the ordering of parsing of different 986bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // styles of attributes? 9877f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseCXX0XAttributes(attrs); 9881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 98920c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley if (TagType == DeclSpec::TST_struct && 990b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor !Tok.is(tok::identifier) && 991b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.getIdentifierInfo() && 992b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor (Tok.is(tok::kw___is_arithmetic) || 993b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_convertible) || 99420c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley Tok.is(tok::kw___is_empty) || 995b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_floating_point) || 996b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_function) || 99720c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley Tok.is(tok::kw___is_fundamental) || 998b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_integral) || 999b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_member_function_pointer) || 1000b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_member_pointer) || 1001b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_pod) || 1002b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_pointer) || 1003b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_same) || 1004877222e2491bbc40a5c74cc100c540983f306b70Douglas Gregor Tok.is(tok::kw___is_scalar) || 1005b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_signed) || 1006b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_unsigned) || 1007b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_void))) { 1008688761409155b47c39eb5dae1b8c6c8a9f43307aDouglas Gregor // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the 1009b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // name of struct templates, but some are keywords in GCC >= 4.3 1010b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // and Clang. Therefore, when we see the token sequence "struct 1011b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // X", make X into a normal identifier rather than a keyword, to 1012b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // allow libstdc++ 4.2 and libc++ to work properly. 1013646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis Tok.getIdentifierInfo()->RevertTokenIDToIdentifier(); 1014b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor Tok.setKind(tok::identifier); 1015b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor } 10161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1017eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Parse the (optional) nested-name-specifier. 1018aa87d33309f505b68c3bfc17486c93e4d224b24fJohn McCall CXXScopeSpec &SS = DS.getTypeSpecScope(); 10194e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus) { 102008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner // "FOO : BAR" is not a potential typo for "FOO::BAR". 102108d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner ColonProtectionRAIIObject X(*this); 1022193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 1023efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext)) 1024207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall DS.SetTypeSpecError(); 10259ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall if (SS.isSet()) 102608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) 102708d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner Diag(Tok, diag::err_expected_ident); 102808d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner } 1029cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor 10302cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams; 10312cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor 1032cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor // Parse the (optional) class name or simple-template-id. 1033e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IdentifierInfo *Name = 0; 1034e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation NameLoc; 103539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateIdAnnotation *TemplateId = 0; 1036e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::identifier)) { 1037e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Name = Tok.getIdentifierInfo(); 1038e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor NameLoc = ConsumeToken(); 1039193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 10404e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Tok.is(tok::less) && getLangOpts().CPlusPlus) { 1041193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // The name was supposed to refer to a template, but didn't. 10422cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // Eat the template argument list and try to continue parsing this as 10432cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // a class (or template thereof). 10442cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor TemplateArgList TemplateArgs; 10452cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor SourceLocation LAngleLoc, RAngleLoc; 1046059101f922de6eb765601459925f4c8914420b23Douglas Gregor if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, SS, 10472cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor true, LAngleLoc, 1048314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor TemplateArgs, RAngleLoc)) { 10492cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // We couldn't parse the template argument list at all, so don't 10502cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // try to give any location information for the list. 10512cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor LAngleLoc = RAngleLoc = SourceLocation(); 10522cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor } 1053193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 10542cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor Diag(NameLoc, diag::err_explicit_spec_non_template) 1055c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) 10562cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor << (TagType == DeclSpec::TST_class? 0 10572cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor : TagType == DeclSpec::TST_struct? 1 10582cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor : 2) 10592cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor << Name 10602cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor << SourceRange(LAngleLoc, RAngleLoc); 1061193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 1062193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // Strip off the last template parameter list if it was empty, since 1063c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor // we've removed its template argument list. 1064c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) { 1065c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor if (TemplateParams && TemplateParams->size() > 1) { 1066c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor TemplateParams->pop_back(); 1067c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor } else { 1068c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor TemplateParams = 0; 1069193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind 1070c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor = ParsedTemplateInfo::NonTemplate; 1071c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor } 1072c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor } else if (TemplateInfo.Kind 1073c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor == ParsedTemplateInfo::ExplicitInstantiation) { 1074c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor // Pretend this is just a forward declaration. 10752cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor TemplateParams = 0; 1076193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind 10772cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor = ParsedTemplateInfo::NonTemplate; 1078193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc 1079c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor = SourceLocation(); 1080c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc 1081c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor = SourceLocation(); 10822cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor } 10832cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor } 108439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor } else if (Tok.is(tok::annot_template_id)) { 108525a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateId = takeTemplateIdAnnotation(Tok); 108639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor NameLoc = ConsumeToken(); 1087cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor 1088059101f922de6eb765601459925f4c8914420b23Douglas Gregor if (TemplateId->Kind != TNK_Type_template && 1089059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->Kind != TNK_Dependent_template_name) { 109039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // The template-name in the simple-template-id refers to 109139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // something other than a class template. Give an appropriate 109239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // error message and skip to the ';'. 109339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor SourceRange Range(NameLoc); 109439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (SS.isNotEmpty()) 109539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor Range.setBegin(SS.getBeginLoc()); 109639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor 109739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template) 109839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor << Name << static_cast<int>(TemplateId->Kind) << Range; 10991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 110039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor DS.SetTypeSpecError(); 110139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor SkipUntil(tok::semi, false, true); 110239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor return; 1103cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor } 1104e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1105e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1106926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // As soon as we're finished parsing the class's template-id, turn access 1107926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // checking back on. 11081af83c444e5a2f6f50a6e1c15e6ebc618ae18a5fRichard Smith SuppressAccess.done(); 1109926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth 11107796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // There are four options here. 11117796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - If we are in a trailing return type, this is always just a reference, 11127796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // and we must not try to parse a definition. For instance, 11137796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // [] () -> struct S { }; 11147796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // does not define a type. 11157796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - If we have 'struct foo {...', 'struct foo :...', 11167796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // 'struct foo final :' or 'struct foo final {', then this is a definition. 11177796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - If we have 'struct foo;', then this is either a forward declaration 11187796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // or a friend declaration, which have to be treated differently. 11197796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - Otherwise we have something like 'struct foo xyz', a reference. 112069730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // However, in type-specifier-seq's, things look like declarations but are 112169730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // just references, e.g. 112269730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // new struct s; 1123d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl // or 112469730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // &T::operator struct s; 112569730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // For these, DSC is DSC_type_specifier. 1126f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall Sema::TagUseKind TUK; 11277796eb5643244f3134834253ce5ea89107ac21c1Richard Smith if (DSC == DSC_trailing) 11287796eb5643244f3134834253ce5ea89107ac21c1Richard Smith TUK = Sema::TUK_Reference; 11297796eb5643244f3134834253ce5ea89107ac21c1Richard Smith else if (Tok.is(tok::l_brace) || 11307796eb5643244f3134834253ce5ea89107ac21c1Richard Smith (getLangOpts().CPlusPlus && Tok.is(tok::colon)) || 11317796eb5643244f3134834253ce5ea89107ac21c1Richard Smith (isCXX0XFinalKeyword() && 11326f42669b7c0b81b07a15a0483aa5e897ce57cb45David Blaikie (NextToken().is(tok::l_brace) || NextToken().is(tok::colon)))) { 1133d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor if (DS.isFriendSpecified()) { 1134d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // C++ [class.friend]p2: 1135d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // A class shall not be defined in a friend declaration. 1136bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith Diag(Tok.getLocation(), diag::err_friend_decl_defines_type) 1137d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor << SourceRange(DS.getFriendSpecLoc()); 1138d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor 1139d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // Skip everything up to the semicolon, so that this looks like a proper 1140d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // friend class (or template thereof) declaration. 1141d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor SkipUntil(tok::semi, true, true); 1142f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = Sema::TUK_Friend; 1143d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor } else { 1144d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // Okay, this is a class definition. 1145f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = Sema::TUK_Definition; 1146d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor } 114769730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith } else if (Tok.is(tok::semi) && DSC != DSC_type_specifier) 1148f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration; 1149e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor else 1150f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = Sema::TUK_Reference; 1151e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1152207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error || 1153f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK != Sema::TUK_Definition)) { 1154207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall if (DS.getTypeSpecType() != DeclSpec::TST_error) { 1155207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall // We have a declaration or reference to an anonymous class. 1156207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall Diag(StartLoc, diag::err_anon_type_definition) 1157207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall << DeclSpec::getSpecifierName(TagType); 1158207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall } 1159e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1160e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SkipUntil(tok::comma, true); 1161e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor return; 1162e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1163e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1164ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor // Create the tag portion of the class or class template. 1165d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall DeclResult TagOrTempResult = true; // invalid 1166d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall TypeResult TypeResult = true; // invalid 11674d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 1168402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor bool Owned = false; 1169f1bbbb49f06a7462476cd88166fccda5feb15cabJohn McCall if (TemplateId) { 11704d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // Explicit specialization, class template partial specialization, 11714d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // or explicit instantiation. 11721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ASTTemplateArgsPtr TemplateArgsPtr(Actions, 117339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->getTemplateArgs(), 117439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->NumArgs); 11754d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && 1176f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK == Sema::TUK_Declaration) { 11774d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // This is an explicit instantiation of a class template. 11784d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TagOrTempResult 117923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnExplicitInstantiation(getCurScope(), 118045f965581935791a018df829a14dff53c1dd8f47Douglas Gregor TemplateInfo.ExternLoc, 11811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateInfo.TemplateLoc, 11824d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TagType, 11831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump StartLoc, 11844d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor SS, 11852b5289b6fd7e3d9899868410a498c081c9595662John McCall TemplateId->Template, 11861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->TemplateNameLoc, 11871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->LAngleLoc, 11884d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TemplateArgsPtr, 11891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->RAngleLoc, 11907f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall attrs.getList()); 119174256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall 119274256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // Friend template-ids are treated as references unless 119374256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // they have template headers, in which case they're ill-formed 119474256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // (FIXME: "template <class T> friend class A<T>::B<int>;"). 119574256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // We diagnose this error in ActOnClassTemplateSpecialization. 1196f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall } else if (TUK == Sema::TUK_Reference || 1197f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall (TUK == Sema::TUK_Friend && 119874256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) { 119955d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara TypeResult = Actions.ActOnTagTemplateIdType(TUK, TagType, StartLoc, 1200059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->SS, 120155d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara TemplateId->TemplateKWLoc, 1202059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->Template, 1203059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->TemplateNameLoc, 1204059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->LAngleLoc, 1205059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateArgsPtr, 120655d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara TemplateId->RAngleLoc); 12074d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor } else { 12084d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // This is an explicit specialization or a class template 12094d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // partial specialization. 12104d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TemplateParameterLists FakedParamLists; 12114d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 12124d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { 12134d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // This looks like an explicit instantiation, because we have 12144d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // something like 12154d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // 12164d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // template class Foo<X> 12174d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // 12183f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // but it actually has a definition. Most likely, this was 12194d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // meant to be an explicit specialization, but the user forgot 12204d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // the '<>' after 'template'. 1221f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall assert(TUK == Sema::TUK_Definition && "Expected a definition here"); 12224d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 12231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump SourceLocation LAngleLoc 12244d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc); 12251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(TemplateId->TemplateNameLoc, 12264d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor diag::err_explicit_instantiation_with_definition) 12274d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor << SourceRange(TemplateInfo.TemplateLoc) 1228849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor << FixItHint::CreateInsertion(LAngleLoc, "<>"); 12294d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 12304d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // Create a fake template parameter list that contains only 12314d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // "template<>", so that we treat this construct as a class 12324d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // template specialization. 12334d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor FakedParamLists.push_back( 12341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Actions.ActOnTemplateParameterList(0, SourceLocation(), 12354d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TemplateInfo.TemplateLoc, 12361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump LAngleLoc, 12371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 0, 0, 12384d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor LAngleLoc)); 12394d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TemplateParams = &FakedParamLists; 12404d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor } 12414d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 12424d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // Build the class template specialization. 12434d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TagOrTempResult 124423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK, 1245d023aec8907831a18d3514a95b843a7ee06b6b5eDouglas Gregor StartLoc, DS.getModulePrivateSpecLoc(), SS, 12462b5289b6fd7e3d9899868410a498c081c9595662John McCall TemplateId->Template, 12471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->TemplateNameLoc, 12481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->LAngleLoc, 124939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateArgsPtr, 12501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->RAngleLoc, 12517f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall attrs.getList(), 1252f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall MultiTemplateParamsArg(Actions, 1253cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor TemplateParams? &(*TemplateParams)[0] : 0, 1254cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor TemplateParams? TemplateParams->size() : 0)); 12554d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor } 12563f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && 1257f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK == Sema::TUK_Declaration) { 12583f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // Explicit instantiation of a member of a class template 12593f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // specialization, e.g., 12603f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // 12613f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // template struct Outer<int>::Inner; 12623f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // 12633f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor TagOrTempResult 126423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnExplicitInstantiation(getCurScope(), 126545f965581935791a018df829a14dff53c1dd8f47Douglas Gregor TemplateInfo.ExternLoc, 12661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateInfo.TemplateLoc, 12671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TagType, StartLoc, SS, Name, 12687f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall NameLoc, attrs.getList()); 12699a34edb710917798aa30263374f624f13b594605John McCall } else if (TUK == Sema::TUK_Friend && 12709a34edb710917798aa30263374f624f13b594605John McCall TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) { 12719a34edb710917798aa30263374f624f13b594605John McCall TagOrTempResult = 12729a34edb710917798aa30263374f624f13b594605John McCall Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(), 12739a34edb710917798aa30263374f624f13b594605John McCall TagType, StartLoc, SS, 12747f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall Name, NameLoc, attrs.getList(), 12759a34edb710917798aa30263374f624f13b594605John McCall MultiTemplateParamsArg(Actions, 12769a34edb710917798aa30263374f624f13b594605John McCall TemplateParams? &(*TemplateParams)[0] : 0, 12779a34edb710917798aa30263374f624f13b594605John McCall TemplateParams? TemplateParams->size() : 0)); 12783f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor } else { 12793f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && 1280f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK == Sema::TUK_Definition) { 12813f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // FIXME: Diagnose this particular error. 12823f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor } 12833f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor 1284c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall bool IsDependent = false; 1285c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall 1286a25c4080a490ea2bab6f54094dd75b19eae83770John McCall // Don't pass down template parameter lists if this is just a tag 1287a25c4080a490ea2bab6f54094dd75b19eae83770John McCall // reference. For example, we don't need the template parameters here: 1288a25c4080a490ea2bab6f54094dd75b19eae83770John McCall // template <class T> class A *makeA(T t); 1289a25c4080a490ea2bab6f54094dd75b19eae83770John McCall MultiTemplateParamsArg TParams; 1290a25c4080a490ea2bab6f54094dd75b19eae83770John McCall if (TUK != Sema::TUK_Reference && TemplateParams) 1291a25c4080a490ea2bab6f54094dd75b19eae83770John McCall TParams = 1292a25c4080a490ea2bab6f54094dd75b19eae83770John McCall MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size()); 1293a25c4080a490ea2bab6f54094dd75b19eae83770John McCall 12943f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // Declaration or definition of a class type 12959a34edb710917798aa30263374f624f13b594605John McCall TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc, 12967f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall SS, Name, NameLoc, attrs.getList(), AS, 1297e761230ae3751b525cadd8066c74ec278ee4ef57Douglas Gregor DS.getModulePrivateSpecLoc(), 1298bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith TParams, Owned, IsDependent, 1299bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith SourceLocation(), false, 1300bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith clang::TypeResult()); 1301c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall 1302c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall // If ActOnTag said the type was dependent, try again with the 1303c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall // less common call. 13049a34edb710917798aa30263374f624f13b594605John McCall if (IsDependent) { 13059a34edb710917798aa30263374f624f13b594605John McCall assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend); 130623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK, 1307193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam SS, Name, StartLoc, NameLoc); 13089a34edb710917798aa30263374f624f13b594605John McCall } 13093f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor } 1310e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1311e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If there is a body, parse it and inform the actions module. 1312f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall if (TUK == Sema::TUK_Definition) { 1313bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall assert(Tok.is(tok::l_brace) || 13144e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie (getLangOpts().CPlusPlus && Tok.is(tok::colon)) || 13158a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson isCXX0XFinalKeyword()); 13164e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus) 1317212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get()); 131807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis else 1319212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get()); 1320e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1321e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1322b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall const char *PrevSpec = 0; 1323b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall unsigned DiagID; 1324b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall bool Result; 1325c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall if (!TypeResult.isInvalid()) { 13260daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, 13270daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara NameLoc.isValid() ? NameLoc : StartLoc, 1328b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall PrevSpec, DiagID, TypeResult.get()); 1329c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall } else if (!TagOrTempResult.isInvalid()) { 13300daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara Result = DS.SetTypeSpecType(TagType, StartLoc, 13310daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara NameLoc.isValid() ? NameLoc : StartLoc, 13320daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara PrevSpec, DiagID, TagOrTempResult.get(), Owned); 1333c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall } else { 1334ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor DS.SetTypeSpecError(); 133566e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson return; 133666e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson } 13371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1338b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall if (Result) 1339fec54013fcd0eb72642741584ca04c1bc292bef8John McCall Diag(StartLoc, DiagID) << PrevSpec; 1340193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 13414ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // At this point, we've successfully parsed a class-specifier in 'definition' 13424ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // form (e.g. "struct foo { int x; }". While we could just return here, we're 13434ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // going to look at what comes after it to improve error recovery. If an 13444ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // impossible token occurs next, we assume that the programmer forgot a ; at 13454ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // the end of the declaration and recover that way. 13464ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // 13474ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // This switch enumerates the valid "follow" set for definition. 1348f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall if (TUK == Sema::TUK_Definition) { 1349b3a4e432c90be98c6d918087750397e86d030368Chris Lattner bool ExpectedSemi = true; 13504ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner switch (Tok.getKind()) { 1351b3a4e432c90be98c6d918087750397e86d030368Chris Lattner default: break; 13524ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner case tok::semi: // struct foo {...} ; 135399c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner case tok::star: // struct foo {...} * P; 135499c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner case tok::amp: // struct foo {...} & R = ... 135599c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner case tok::identifier: // struct foo {...} V ; 135699c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner case tok::r_paren: //(struct foo {...} ) {4} 135799c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner case tok::annot_cxxscope: // struct foo {...} a:: b; 135899c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner case tok::annot_typename: // struct foo {...} a ::b; 135999c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner case tok::annot_template_id: // struct foo {...} a<int> ::b; 1360c2e1c1af8ffe750b827284f207b9207112c7cc4eChris Lattner case tok::l_paren: // struct foo {...} ( x); 136116acfee729e00536af827935ccfcf69be721e462Chris Lattner case tok::comma: // __builtin_offsetof(struct foo{...} , 1362b3a4e432c90be98c6d918087750397e86d030368Chris Lattner ExpectedSemi = false; 1363b3a4e432c90be98c6d918087750397e86d030368Chris Lattner break; 1364b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // Type qualifiers 1365b3a4e432c90be98c6d918087750397e86d030368Chris Lattner case tok::kw_const: // struct foo {...} const x; 1366b3a4e432c90be98c6d918087750397e86d030368Chris Lattner case tok::kw_volatile: // struct foo {...} volatile x; 1367b3a4e432c90be98c6d918087750397e86d030368Chris Lattner case tok::kw_restrict: // struct foo {...} restrict x; 1368b3a4e432c90be98c6d918087750397e86d030368Chris Lattner case tok::kw_inline: // struct foo {...} inline foo() {}; 136999c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner // Storage-class specifiers 137099c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner case tok::kw_static: // struct foo {...} static x; 137199c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner case tok::kw_extern: // struct foo {...} extern x; 137299c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner case tok::kw_typedef: // struct foo {...} typedef x; 137399c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner case tok::kw_register: // struct foo {...} register x; 137499c952046600f6bfccf315aa7ad5b1be2d242cc3Chris Lattner case tok::kw_auto: // struct foo {...} auto x; 1375af1fc7af351758b0ea0d285bdfe5640128109a4eRichard Smith case tok::kw_mutable: // struct foo {...} mutable x; 1376af1fc7af351758b0ea0d285bdfe5640128109a4eRichard Smith case tok::kw_constexpr: // struct foo {...} constexpr x; 1377b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // As shown above, type qualifiers and storage class specifiers absolutely 1378b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // can occur after class specifiers according to the grammar. However, 1379fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner // almost no one actually writes code like this. If we see one of these, 1380b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // it is much more likely that someone missed a semi colon and the 1381b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // type/storage class specifier we're seeing is part of the *next* 1382b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // intended declaration, as in: 1383b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // 1384b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // struct foo { ... } 1385b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // typedef int X; 1386b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // 1387b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // We'd really like to emit a missing semicolon error instead of emitting 1388b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // an error on the 'int' saying that you can't have two type specifiers in 1389b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // the same declaration of X. Because of this, we look ahead past this 1390b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // token to see if it's a type specifier. If so, we know the code is 1391b3a4e432c90be98c6d918087750397e86d030368Chris Lattner // otherwise invalid, so we can produce the expected semi error. 1392b3a4e432c90be98c6d918087750397e86d030368Chris Lattner if (!isKnownToBeTypeSpecifier(NextToken())) 1393b3a4e432c90be98c6d918087750397e86d030368Chris Lattner ExpectedSemi = false; 13944ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner break; 1395193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 1396193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam case tok::r_brace: // struct bar { struct foo {...} } 13974ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // Missing ';' at end of struct is accepted as an extension in C mode. 13984e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().CPlusPlus) 1399b3a4e432c90be98c6d918087750397e86d030368Chris Lattner ExpectedSemi = false; 1400b3a4e432c90be98c6d918087750397e86d030368Chris Lattner break; 1401b3a4e432c90be98c6d918087750397e86d030368Chris Lattner } 1402193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 1403cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith // C++ [temp]p3 In a template-declaration which defines a class, no 1404cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith // declarator is permitted. 1405cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith if (TemplateInfo.Kind) 1406cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith ExpectedSemi = true; 1407cf6b0a20c697ba8daf2dff3a4cce2a028b33cb48Richard Smith 1408b3a4e432c90be98c6d918087750397e86d030368Chris Lattner if (ExpectedSemi) { 14094ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, 14104ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner TagType == DeclSpec::TST_class ? "class" 14114ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner : TagType == DeclSpec::TST_struct? "struct" : "union"); 14124ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // Push this token back into the preprocessor and change our current token 14134ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // to ';' so that the rest of the code recovers as though there were an 14144ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // ';' after the definition. 14154ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner PP.EnterToken(Tok); 1416193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam Tok.setKind(tok::semi); 14174ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner } 14184ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner } 1419e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 1420e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 14211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived]. 1422e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1423e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-clause : [C++ class.derived] 1424e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ':' base-specifier-list 1425e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier-list: 1426e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier '...'[opt] 1427e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier-list ',' base-specifier '...'[opt] 1428d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseBaseClause(Decl *ClassDecl) { 1429e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor assert(Tok.is(tok::colon) && "Not a base clause"); 1430e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 1431e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1432f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Build up an array of parsed base specifiers. 14335f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CXXBaseSpecifier *, 8> BaseInfo; 1434f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor 1435e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor while (true) { 1436e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse a base-specifier. 1437f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor BaseResult Result = ParseBaseSpecifier(ClassDecl); 14385ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor if (Result.isInvalid()) { 1439e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Skip the rest of this base specifier, up until the comma or 1440e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // opening brace. 1441f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor SkipUntil(tok::comma, tok::l_brace, true, true); 1442f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor } else { 1443f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Add this to our array of base specifiers. 14445ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor BaseInfo.push_back(Result.get()); 1445e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1446e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1447e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If the next token is a comma, consume it and keep reading 1448e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // base-specifiers. 1449e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.isNot(tok::comma)) break; 14501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1451e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Consume the comma. 1452e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 1453e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1454f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor 1455f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Attach the base specifiers 1456beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size()); 1457e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 1458e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1459e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is 1460e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example: 1461e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class foo : public bar, virtual private baz { 1462e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers. 1463e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1464e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier: [C++ class.derived] 1465e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ::[opt] nested-name-specifier[opt] class-name 1466e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt] 146709048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// base-type-specifier 1468e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt] 146909048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// base-type-specifier 1470d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) { 1471e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor bool IsVirtual = false; 1472e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation StartLoc = Tok.getLocation(); 1473e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1474e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the 'virtual' keyword. 1475e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw_virtual)) { 1476e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 1477e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IsVirtual = true; 1478e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1479e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1480e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse an (optional) access specifier. 1481e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor AccessSpecifier Access = getAccessSpecifierIfPresent(); 148292f883177b162928a8e632e4e3b93fafd2b26072John McCall if (Access != AS_none) 1483e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 14841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1485e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the 'virtual' keyword (again!), in case it came after the 1486e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // access specifier. 1487e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw_virtual)) { 1488e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation VirtualLoc = ConsumeToken(); 1489e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (IsVirtual) { 1490e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Complain about duplicate 'virtual' 14911ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(VirtualLoc, diag::err_dup_virtual) 1492849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor << FixItHint::CreateRemoval(VirtualLoc); 1493e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1494e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1495e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IsVirtual = true; 1496e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1497e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 149842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Parse the class-name. 14997f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor SourceLocation EndLocation; 150022216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie SourceLocation BaseLoc; 150122216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation); 150231a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor if (BaseType.isInvalid()) 150342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return true; 15041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1505f90b27ad077c3339b62befc892382845339f9490Douglas Gregor // Parse the optional ellipsis (for a pack expansion). The ellipsis is 1506f90b27ad077c3339b62befc892382845339f9490Douglas Gregor // actually part of the base-specifier-list grammar productions, but we 1507f90b27ad077c3339b62befc892382845339f9490Douglas Gregor // parse it here for convenience. 1508f90b27ad077c3339b62befc892382845339f9490Douglas Gregor SourceLocation EllipsisLoc; 1509f90b27ad077c3339b62befc892382845339f9490Douglas Gregor if (Tok.is(tok::ellipsis)) 1510f90b27ad077c3339b62befc892382845339f9490Douglas Gregor EllipsisLoc = ConsumeToken(); 1511f90b27ad077c3339b62befc892382845339f9490Douglas Gregor 15121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Find the complete source range for the base-specifier. 15137f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor SourceRange Range(StartLoc, EndLocation); 15141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1515e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Notify semantic analysis that we have parsed a complete 1516e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // base-specifier. 1517a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access, 1518f90b27ad077c3339b62befc892382845339f9490Douglas Gregor BaseType.get(), BaseLoc, EllipsisLoc); 1519e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 1520e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1521e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is 1522e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier. 1523e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1524e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// access-specifier: [C++ class.derived] 1525e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'private' 1526e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'protected' 1527e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public' 15281eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAccessSpecifier Parser::getAccessSpecifierIfPresent() const { 1529e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor switch (Tok.getKind()) { 1530e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor default: return AS_none; 1531e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_private: return AS_private; 1532e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_protected: return AS_protected; 1533e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_public: return AS_public; 1534e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1535e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 15364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 153774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor/// \brief If the given declarator has any parts for which parsing has to be 153874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor/// delayed, e.g., default arguments or an exception-specification, create a 153974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor/// late-parsed method declaration record to handle the parsing at the end of 154074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor/// the class definition. 154174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregorvoid Parser::HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo, 154274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor Decl *ThisDecl) { 1543d33133cdc1af466f9c276249b2621be03867888bEli Friedman // We just declared a member function. If this member function 154474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // has any default arguments or an exception-specification, we'll need to 154574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // parse them later. 1546d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateParsedMethodDeclaration *LateMethod = 0; 15471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump DeclaratorChunk::FunctionTypeInfo &FTI 1548075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara = DeclaratorInfo.getFunctionTypeInfo(); 154974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 155074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // If there was a delayed exception-specification, hold onto its tokens. 155174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor if (FTI.getExceptionSpecType() == EST_Delayed) { 155274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Push this method onto the stack of late-parsed method 155374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // declarations. 155474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor LateMethod = new LateParsedMethodDeclaration(this, ThisDecl); 155574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor getCurrentClass().LateParsedDeclarations.push_back(LateMethod); 155674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor LateMethod->TemplateScope = getCurScope()->isTemplateParamScope(); 155774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 155874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Stash the exception-specification tokens in the late-pased mthod. 155974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens; 156074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor FTI.ExceptionSpecTokens = 0; 156174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 156274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Reserve space for the parameters. 156374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor LateMethod->DefaultArgs.reserve(FTI.NumArgs); 156474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor } 156574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 1566d33133cdc1af466f9c276249b2621be03867888bEli Friedman for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) { 1567d33133cdc1af466f9c276249b2621be03867888bEli Friedman if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) { 1568d33133cdc1af466f9c276249b2621be03867888bEli Friedman if (!LateMethod) { 1569d33133cdc1af466f9c276249b2621be03867888bEli Friedman // Push this method onto the stack of late-parsed method 1570d33133cdc1af466f9c276249b2621be03867888bEli Friedman // declarations. 1571d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor LateMethod = new LateParsedMethodDeclaration(this, ThisDecl); 1572d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor getCurrentClass().LateParsedDeclarations.push_back(LateMethod); 157323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor LateMethod->TemplateScope = getCurScope()->isTemplateParamScope(); 1574d33133cdc1af466f9c276249b2621be03867888bEli Friedman 1575d33133cdc1af466f9c276249b2621be03867888bEli Friedman // Add all of the parameters prior to this one (they don't 1576d33133cdc1af466f9c276249b2621be03867888bEli Friedman // have default arguments). 1577d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateMethod->DefaultArgs.reserve(FTI.NumArgs); 1578d33133cdc1af466f9c276249b2621be03867888bEli Friedman for (unsigned I = 0; I < ParamIdx; ++I) 1579d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateMethod->DefaultArgs.push_back( 15808f8210c47797f013e0fb24a26f9c4751b10783feDouglas Gregor LateParsedDefaultArgument(FTI.ArgInfo[I].Param)); 1581d33133cdc1af466f9c276249b2621be03867888bEli Friedman } 1582d33133cdc1af466f9c276249b2621be03867888bEli Friedman 158374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Add this parameter to the list of parameters (it may or may 1584d33133cdc1af466f9c276249b2621be03867888bEli Friedman // not have a default argument). 1585d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateMethod->DefaultArgs.push_back( 1586d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param, 1587d33133cdc1af466f9c276249b2621be03867888bEli Friedman FTI.ArgInfo[ParamIdx].DefaultArgTokens)); 1588d33133cdc1af466f9c276249b2621be03867888bEli Friedman } 1589d33133cdc1af466f9c276249b2621be03867888bEli Friedman } 1590d33133cdc1af466f9c276249b2621be03867888bEli Friedman} 1591d33133cdc1af466f9c276249b2621be03867888bEli Friedman 15921c94c16317c1a35c1549e022958188eea2567089Richard Smith/// isCXX0XVirtSpecifier - Determine whether the given token is a C++0x 15931f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier. 15941f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 15951f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier: 15961f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// override 15971f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// final 15981c94c16317c1a35c1549e022958188eea2567089Richard SmithVirtSpecifiers::Specifier Parser::isCXX0XVirtSpecifier(const Token &Tok) const { 15994e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().CPlusPlus) 1600cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson return VirtSpecifiers::VS_None; 1601cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 1602b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (Tok.is(tok::identifier)) { 1603b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson IdentifierInfo *II = Tok.getIdentifierInfo(); 16041f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 16057eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson // Initialize the contextual keywords. 16067eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson if (!Ident_final) { 16077eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson Ident_final = &PP.getIdentifierTable().get("final"); 16087eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson Ident_override = &PP.getIdentifierTable().get("override"); 16097eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson } 16107eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson 1611b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (II == Ident_override) 1612b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return VirtSpecifiers::VS_Override; 16131f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 1614b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (II == Ident_final) 1615b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return VirtSpecifiers::VS_Final; 1616b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson } 1617b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson 1618b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return VirtSpecifiers::VS_None; 16191f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson} 16201f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 16211f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// ParseOptionalCXX0XVirtSpecifierSeq - Parse a virt-specifier-seq. 16221f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 16231f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq: 16241f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier 16251f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq virt-specifier 1626b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlssonvoid Parser::ParseOptionalCXX0XVirtSpecifierSeq(VirtSpecifiers &VS) { 1627b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson while (true) { 1628cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson VirtSpecifiers::Specifier Specifier = isCXX0XVirtSpecifier(); 1629b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (Specifier == VirtSpecifiers::VS_None) 1630b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return; 1631b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson 1632b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson // C++ [class.mem]p8: 1633b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson // A virt-specifier-seq shall contain at most one of each virt-specifier. 1634cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson const char *PrevSpec = 0; 163546127a96b6dd6b93aa18d5f7a55bc2db8b52a2c9Anders Carlsson if (VS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec)) 1636b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier) 1637b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson << PrevSpec 1638b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson << FixItHint::CreateRemoval(Tok.getLocation()); 1639b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson 16404e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Diag(Tok.getLocation(), getLangOpts().CPlusPlus0x ? 16417fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_override_control_keyword : 16427fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::ext_override_control_keyword) 16437fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith << VirtSpecifiers::getSpecifierName(Specifier); 1644b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson ConsumeToken(); 1645b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson } 16461f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson} 16471f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 16488a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson/// isCXX0XFinalKeyword - Determine whether the next token is a C++0x 16498a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson/// contextual 'final' keyword. 16508a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlssonbool Parser::isCXX0XFinalKeyword() const { 16514e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().CPlusPlus) 16528a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson return false; 1653cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 16548a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson if (!Tok.is(tok::identifier)) 16558a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson return false; 1656cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 16578a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson // Initialize the contextual keywords. 16588a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson if (!Ident_final) { 16598a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson Ident_final = &PP.getIdentifierTable().get("final"); 16608a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson Ident_override = &PP.getIdentifierTable().get("override"); 1661cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson } 16628a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson 16638a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson return Tok.getIdentifierInfo() == Ident_final; 1664cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson} 1665cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 16664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration. 16674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 16684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declaration: 16694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// decl-specifier-seq[opt] member-declarator-list[opt] ';' 16704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// function-definition ';'[opt] 16714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO] 16724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// using-declaration [TODO] 1673511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration 16745aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson/// template-declaration 1675bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU] '__extension__' member-declaration 16764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 16774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator-list: 16784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator 16794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator-list ',' member-declarator 16804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 16814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator: 16821f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// declarator virt-specifier-seq[opt] pure-specifier[opt] 16834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// declarator constant-initializer[opt] 16847a614d8380297fcd2bc23986241905d97222948cRichard Smith/// [C++11] declarator brace-or-equal-initializer[opt] 16854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// identifier[opt] ':' constant-expression 16864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 16871f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq: 16881f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier 16891f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq virt-specifier 16901f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 16911f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier: 16921f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// override 16931f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// final 16941f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 1695e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl/// pure-specifier: 16964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// '= 0' 16974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 16984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// constant-initializer: 16994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// '=' constant-expression 17004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 170137b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregorvoid Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, 17025f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen AttributeList *AccessAttrs, 1703c9068d7dd94d439cec66c421115d15303e481025John McCall const ParsedTemplateInfo &TemplateInfo, 1704c9068d7dd94d439cec66c421115d15303e481025John McCall ParsingDeclRAIIObject *TemplateDiags) { 17058a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor if (Tok.is(tok::at)) { 17064e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjC1 && NextToken().isObjCAtKeyword(tok::objc_defs)) 17078a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor Diag(Tok, diag::err_at_defs_cxx); 17088a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor else 17098a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor Diag(Tok, diag::err_at_in_class); 17108a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor 17118a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor ConsumeToken(); 17128a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor SkipUntil(tok::r_brace); 17138a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor return; 17148a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor } 17158a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor 171660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // Access declarations. 171760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall if (!TemplateInfo.Kind && 171860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) && 17199ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall !TryAnnotateCXXScopeToken() && 172060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall Tok.is(tok::annot_cxxscope)) { 172160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall bool isAccessDecl = false; 172260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall if (NextToken().is(tok::identifier)) 172360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall isAccessDecl = GetLookAheadToken(2).is(tok::semi); 172460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall else 172560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall isAccessDecl = NextToken().is(tok::kw_operator); 172660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 172760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall if (isAccessDecl) { 172860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // Collect the scope specifier token we annotated earlier. 172960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall CXXScopeSpec SS; 1730efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 1731efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor /*EnteringContext=*/false); 173260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 173360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // Try to parse an unqualified-id. 1734e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara SourceLocation TemplateKWLoc; 173560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall UnqualifiedId Name; 1736e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), 1737e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara TemplateKWLoc, Name)) { 173860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall SkipUntil(tok::semi); 173960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall return; 174060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall } 174160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 174260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // TODO: recover from mistakenly-qualified operator declarations. 174360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall if (ExpectAndConsume(tok::semi, 174460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall diag::err_expected_semi_after, 174560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall "access declaration", 174660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall tok::semi)) 174760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall return; 174860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 174923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnUsingDeclaration(getCurScope(), AS, 175060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall false, SourceLocation(), 175160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall SS, Name, 175260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall /* AttrList */ 0, 175360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall /* IsTypeName */ false, 175460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall SourceLocation()); 175560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall return; 175660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall } 175760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall } 175860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 1759511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson // static_assert-declaration 1760c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne if (Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) { 176137b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor // FIXME: Check for templates 176297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner SourceLocation DeclEnd; 176397144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner ParseStaticAssertDeclaration(DeclEnd); 1764682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 1765682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner } 17661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1767682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner if (Tok.is(tok::kw_template)) { 17681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump assert(!TemplateInfo.TemplateParams && 176937b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor "Nested template improperly parsed?"); 177097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner SourceLocation DeclEnd; 17711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd, 17725f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen AS, AccessAttrs); 1773682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 1774682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner } 17755aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson 1776bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner // Handle: member-declaration ::= '__extension__' member-declaration 1777bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner if (Tok.is(tok::kw___extension__)) { 1778bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner // __extension__ silences extension warnings in the subexpression. 1779bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner ExtensionRAIIObject O(Diags); // Use RAII to do this. 1780bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner ConsumeToken(); 17815f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen return ParseCXXClassMemberDeclaration(AS, AccessAttrs, 17825f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen TemplateInfo, TemplateDiags); 1783bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner } 17849cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 17854ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it 17864ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // is a bitfield. 1787a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner ColonProtectionRAIIObject X(*this); 1788193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 17890b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributesWithRange attrs(AttrFactory); 1790bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // Optional C++0x attribute-specifier 17917f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseCXX0XAttributes(attrs); 17927f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseMicrosoftAttributes(attrs); 1793bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 17949cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (Tok.is(tok::kw_using)) { 17957f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ProhibitAttributes(attrs); 17961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17979cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Eat 'using'. 17989cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SourceLocation UsingLoc = ConsumeToken(); 17999cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 18009cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (Tok.is(tok::kw_namespace)) { 18019cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor Diag(UsingLoc, diag::err_using_namespace_in_class); 18029cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SkipUntil(tok::semi, true, true); 1803ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner } else { 18049cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SourceLocation DeclEnd; 18053e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // Otherwise, it must be a using-declaration or an alias-declaration. 180678b810559d89e996e00684335407443936ce34a1John McCall ParseUsingDeclaration(Declarator::MemberContext, TemplateInfo, 180778b810559d89e996e00684335407443936ce34a1John McCall UsingLoc, DeclEnd, AS); 18089cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 18099cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor return; 18109cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 18119cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 18122287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins // Hold late-parsed attributes so we can attach a Decl to them later. 18132287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins LateParsedAttrList CommonLateParsedAttrs; 18142287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins 18154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // decl-specifier-seq: 18164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the common declaration-specifiers piece. 1817c9068d7dd94d439cec66c421115d15303e481025John McCall ParsingDeclSpec DS(*this, TemplateDiags); 18187f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall DS.takeAttributesFrom(attrs); 18192287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class, 18202287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins &CommonLateParsedAttrs); 18214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 1822f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall MultiTemplateParamsArg TemplateParams(Actions, 1823dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0, 1824dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0); 1825dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall 18264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) { 18274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 1828d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl *TheDecl = 18290f4be74ff0273e505d383f89174ef539828424edChandler Carruth Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS, TemplateParams); 1830c9068d7dd94d439cec66c421115d15303e481025John McCall DS.complete(TheDecl); 183167d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall return; 18324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 183307952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis 183454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext); 18354867347e82648d3baf09524b98b09c297a5a198fNico Weber VirtSpecifiers VS; 18364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 1837eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // Hold late-parsed attributes so we can attach a Decl to them later. 1838eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski LateParsedAttrList LateParsedAttrs; 1839eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski 1840a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor SourceLocation EqualLoc; 1841a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor bool HasInitializer = false; 1842a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor ExprResult Init; 18433a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.isNot(tok::colon)) { 1844a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 1845a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner ColonProtectionRAIIObject X(*this); 1846a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner 18473a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // Parse the first declarator. 18483a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 184974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Error parsin g the declarator? 185010bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor if (!DeclaratorInfo.hasName()) { 18513a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // If so, skip until the semi-colon or a }. 1852d941fa4ff0d0d64b5a541dbd4f99693bff7f6e8dSebastian Redl SkipUntil(tok::r_brace, true, true); 18533a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.is(tok::semi)) 18543a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeToken(); 1855682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 18564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 18574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 18584867347e82648d3baf09524b98b09c297a5a198fNico Weber ParseOptionalCXX0XVirtSpecifierSeq(VS); 18594867347e82648d3baf09524b98b09c297a5a198fNico Weber 18601b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson // If attributes exist after the declarator, but before an '{', parse them. 1861eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); 18621b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson 18636a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet // MSVC permits pure specifier on inline functions declared at class scope. 18646a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet // Hence check for =0 before checking for function definition. 18654e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().MicrosoftExt && Tok.is(tok::equal) && 18666a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet DeclaratorInfo.isFunctionDeclarator() && 18676a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet NextToken().is(tok::numeric_constant)) { 1868a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor EqualLoc = ConsumeToken(); 18696a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet Init = ParseInitializer(); 18706a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet if (Init.isInvalid()) 18716a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet SkipUntil(tok::comma, true, true); 1872a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor else 1873a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor HasInitializer = true; 18746a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet } 18756a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet 187645fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor FunctionDefinitionKind DefinitionKind = FDK_Declaration; 18773a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // function-definition: 18787a614d8380297fcd2bc23986241905d97222948cRichard Smith // 18797a614d8380297fcd2bc23986241905d97222948cRichard Smith // In C++11, a non-function declarator followed by an open brace is a 18807a614d8380297fcd2bc23986241905d97222948cRichard Smith // braced-init-list for an in-class member initialization, not an 18817a614d8380297fcd2bc23986241905d97222948cRichard Smith // erroneous function definition. 18824e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Tok.is(tok::l_brace) && !getLangOpts().CPlusPlus0x) { 188345fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Definition; 1884e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } else if (DeclaratorInfo.isFunctionDeclarator()) { 18857a614d8380297fcd2bc23986241905d97222948cRichard Smith if (Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) { 188645fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Definition; 1887e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } else if (Tok.is(tok::equal)) { 1888e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt const Token &KW = NextToken(); 188945fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor if (KW.is(tok::kw_default)) 189045fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Defaulted; 189145fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor else if (KW.is(tok::kw_delete)) 189245fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Deleted; 1893e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } 1894e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } 1895e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt 189645fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor if (DefinitionKind) { 18973a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (!DeclaratorInfo.isFunctionDeclarator()) { 189865ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params); 18993a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeBrace(); 190065ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu SkipUntil(tok::r_brace, /*StopAtSemi*/false); 19019ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor 19029ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor // Consume the optional ';' 19039ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor if (Tok.is(tok::semi)) 19049ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor ConsumeToken(); 1905682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 19063a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 19073a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis 19083a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 190965ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu Diag(DeclaratorInfo.getIdentifierLoc(), 191065ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu diag::err_function_declared_typedef); 19113a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // This recovery skips the entire function body. It would be nice 19123a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // to simply call ParseCXXInlineMethodDef() below, however Sema 19133a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // assumes the declarator represents a function, not a typedef. 19143a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeBrace(); 191565ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu SkipUntil(tok::r_brace, /*StopAtSemi*/false); 19169ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor 19179ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor // Consume the optional ';' 19189ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor if (Tok.is(tok::semi)) 19199ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor ConsumeToken(); 1920682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 19213a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 19224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 1923eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski Decl *FunDecl = 19245f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo, TemplateInfo, 192545fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor VS, DefinitionKind, Init); 1926eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski 19272287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) { 19282287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins CommonLateParsedAttrs[i]->addDecl(FunDecl); 19292287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins } 1930eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) { 19312287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins LateParsedAttrs[i]->addDecl(FunDecl); 1932eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski } 1933eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski LateParsedAttrs.clear(); 1934e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt 1935e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt // Consume the ';' - it's optional unless we have a delete or default 1936e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt if (Tok.is(tok::semi)) { 19379ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor ConsumeToken(); 1938e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } 19399ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor 1940682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 19413a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 19424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 19434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 19444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator-list: 19454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator 19464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator-list ',' member-declarator 19474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 19485f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Decl *, 8> DeclsInGroup; 194960d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult BitfieldSize; 19501c94c16317c1a35c1549e022958188eea2567089Richard Smith bool ExpectSemi = true; 19514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 19524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis while (1) { 19534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator: 19544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // declarator pure-specifier[opt] 19557a614d8380297fcd2bc23986241905d97222948cRichard Smith // declarator brace-or-equal-initializer[opt] 19564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // identifier[opt] ':' constant-expression 19574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::colon)) { 19584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 19590e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl BitfieldSize = ParseConstantExpression(); 19600e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (BitfieldSize.isInvalid()) 19614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::comma, true, true); 19624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 19631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1964e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner // If a simple-asm-expr is present, parse it. 1965e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner if (Tok.is(tok::kw_asm)) { 1966e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner SourceLocation Loc; 196760d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AsmLabel(ParseSimpleAsm(&Loc)); 1968e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner if (AsmLabel.isInvalid()) 1969e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner SkipUntil(tok::comma, true, true); 1970e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner 1971e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner DeclaratorInfo.setAsmLabel(AsmLabel.release()); 1972e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner DeclaratorInfo.SetRangeEnd(Loc); 1973e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner } 1974e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner 19754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If attributes exist after the declarator, parse them. 1976eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); 19774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 19787a614d8380297fcd2bc23986241905d97222948cRichard Smith // FIXME: When g++ adds support for this, we'll need to check whether it 19797a614d8380297fcd2bc23986241905d97222948cRichard Smith // goes before or after the GNU attributes and __asm__. 19807a614d8380297fcd2bc23986241905d97222948cRichard Smith ParseOptionalCXX0XVirtSpecifierSeq(VS); 19817a614d8380297fcd2bc23986241905d97222948cRichard Smith 19827a614d8380297fcd2bc23986241905d97222948cRichard Smith bool HasDeferredInitializer = false; 1983a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor if ((Tok.is(tok::equal) || Tok.is(tok::l_brace)) && !HasInitializer) { 19847a614d8380297fcd2bc23986241905d97222948cRichard Smith if (BitfieldSize.get()) { 19857a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(Tok, diag::err_bitfield_member_init); 19867a614d8380297fcd2bc23986241905d97222948cRichard Smith SkipUntil(tok::comma, true, true); 19877a614d8380297fcd2bc23986241905d97222948cRichard Smith } else { 1988147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor HasInitializer = true; 1989555f57e3549fb5cc963a2ce38180c4f3643a6f95Douglas Gregor HasDeferredInitializer = !DeclaratorInfo.isDeclarationOfFunction() && 19907a614d8380297fcd2bc23986241905d97222948cRichard Smith DeclaratorInfo.getDeclSpec().getStorageClassSpec() 1991c2cdd5354aba8d6a74c45231829f3bbbbfeb2781Richard Smith != DeclSpec::SCS_static && 1992c2cdd5354aba8d6a74c45231829f3bbbbfeb2781Richard Smith DeclaratorInfo.getDeclSpec().getStorageClassSpec() 1993c2cdd5354aba8d6a74c45231829f3bbbbfeb2781Richard Smith != DeclSpec::SCS_typedef; 19947a614d8380297fcd2bc23986241905d97222948cRichard Smith } 19957a614d8380297fcd2bc23986241905d97222948cRichard Smith } 19967a614d8380297fcd2bc23986241905d97222948cRichard Smith 199707952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // NOTE: If Sema is the Action module and declarator is an instance field, 1998682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner // this call will *not* return the created decl; It will return null. 199907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // See Sema::ActOnCXXMemberDeclarator for details. 200067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall 2001d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl *ThisDecl = 0; 200267d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall if (DS.isFriendSpecified()) { 2003bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall // TODO: handle initializers, bitfields, 'delete' 200423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo, 2005bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall move(TemplateParams)); 200637b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor } else { 200723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, 200867d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall DeclaratorInfo, 200937b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor move(TemplateParams), 201067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall BitfieldSize.release(), 20112c712f50cd56eaf3662989b556e9c6b1e8fcd11aKaelyn Uhrain VS, HasDeferredInitializer); 20125f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen if (AccessAttrs) 20135f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs, 20145f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen false, true); 201537b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor } 2016147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor 2017eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // Set the Decl for any late parsed attributes 20182287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) { 20192287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins CommonLateParsedAttrs[i]->addDecl(ThisDecl); 20202287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins } 2021eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) { 20222287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins LateParsedAttrs[i]->addDecl(ThisDecl); 2023eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski } 2024eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski LateParsedAttrs.clear(); 2025eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski 2026147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // Handle the initializer. 20277a614d8380297fcd2bc23986241905d97222948cRichard Smith if (HasDeferredInitializer) { 2028147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // The initializer was deferred; parse it and cache the tokens. 20294e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Diag(Tok, getLangOpts().CPlusPlus0x ? 20307fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_nonstatic_member_init : 20317fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::ext_nonstatic_member_init); 20327fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 20337a614d8380297fcd2bc23986241905d97222948cRichard Smith if (DeclaratorInfo.isArrayOfUnknownBound()) { 20347a614d8380297fcd2bc23986241905d97222948cRichard Smith // C++0x [dcl.array]p3: An array bound may also be omitted when the 20357a614d8380297fcd2bc23986241905d97222948cRichard Smith // declarator is followed by an initializer. 20367a614d8380297fcd2bc23986241905d97222948cRichard Smith // 20377a614d8380297fcd2bc23986241905d97222948cRichard Smith // A brace-or-equal-initializer for a member-declarator is not an 20383164c14cadbb09a05ba811602221e9156077cf44David Blaikie // initializer in the grammar, so this is ill-formed. 20397a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(Tok, diag::err_incomplete_array_member_init); 20407a614d8380297fcd2bc23986241905d97222948cRichard Smith SkipUntil(tok::comma, true, true); 20413164c14cadbb09a05ba811602221e9156077cf44David Blaikie if (ThisDecl) 20423164c14cadbb09a05ba811602221e9156077cf44David Blaikie // Avoid later warnings about a class member of incomplete type. 20433164c14cadbb09a05ba811602221e9156077cf44David Blaikie ThisDecl->setInvalidDecl(); 20447a614d8380297fcd2bc23986241905d97222948cRichard Smith } else 20457a614d8380297fcd2bc23986241905d97222948cRichard Smith ParseCXXNonStaticMemberInitializer(ThisDecl); 2046147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor } else if (HasInitializer) { 2047147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // Normal initializer. 2048a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor if (!Init.isUsable()) 2049552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor Init = ParseCXXMemberInitializer(ThisDecl, 2050a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor DeclaratorInfo.isDeclarationOfFunction(), EqualLoc); 2051a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor 2052147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor if (Init.isInvalid()) 2053147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor SkipUntil(tok::comma, true, true); 2054147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor else if (ThisDecl) 205533deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid(), 2056a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor DS.getTypeSpecType() == DeclSpec::TST_auto); 2057147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static) { 2058147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // No initializer. 2059147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor Actions.ActOnUninitializedDecl(ThisDecl, 2060147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor DS.getTypeSpecType() == DeclSpec::TST_auto); 20617a614d8380297fcd2bc23986241905d97222948cRichard Smith } 2062147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor 2063147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor if (ThisDecl) { 2064147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor Actions.FinalizeDeclaration(ThisDecl); 2065147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor DeclsInGroup.push_back(ThisDecl); 2066147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor } 2067147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor 2068147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor if (DeclaratorInfo.isFunctionDeclarator() && 2069147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor DeclaratorInfo.getDeclSpec().getStorageClassSpec() 2070147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor != DeclSpec::SCS_typedef) { 207174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl); 2072147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor } 2073147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor 2074147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor DeclaratorInfo.complete(ThisDecl); 20757a614d8380297fcd2bc23986241905d97222948cRichard Smith 20764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If we don't have a comma, it is either the end of the list (a ';') 20774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // or an error, bail out. 20784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.isNot(tok::comma)) 20794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 20801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Consume the comma. 20821c94c16317c1a35c1549e022958188eea2567089Richard Smith SourceLocation CommaLoc = ConsumeToken(); 20831c94c16317c1a35c1549e022958188eea2567089Richard Smith 20841c94c16317c1a35c1549e022958188eea2567089Richard Smith if (Tok.isAtStartOfLine() && 20851c94c16317c1a35c1549e022958188eea2567089Richard Smith !MightBeDeclarator(Declarator::MemberContext)) { 20861c94c16317c1a35c1549e022958188eea2567089Richard Smith // This comma was followed by a line-break and something which can't be 20871c94c16317c1a35c1549e022958188eea2567089Richard Smith // the start of a declarator. The comma was probably a typo for a 20881c94c16317c1a35c1549e022958188eea2567089Richard Smith // semicolon. 20891c94c16317c1a35c1549e022958188eea2567089Richard Smith Diag(CommaLoc, diag::err_expected_semi_declaration) 20901c94c16317c1a35c1549e022958188eea2567089Richard Smith << FixItHint::CreateReplacement(CommaLoc, ";"); 20911c94c16317c1a35c1549e022958188eea2567089Richard Smith ExpectSemi = false; 20921c94c16317c1a35c1549e022958188eea2567089Richard Smith break; 20931c94c16317c1a35c1549e022958188eea2567089Richard Smith } 20941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the next declarator. 20964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclaratorInfo.clear(); 20974867347e82648d3baf09524b98b09c297a5a198fNico Weber VS.clear(); 2098147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor BitfieldSize = true; 2099a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor Init = true; 2100a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor HasInitializer = false; 21017984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith DeclaratorInfo.setCommaLoc(CommaLoc); 21021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Attributes are only allowed on the second declarator. 21047f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseGNUAttributes(DeclaratorInfo); 21054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 21063a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.isNot(tok::colon)) 21073a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 21084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 21094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 21101c94c16317c1a35c1549e022958188eea2567089Richard Smith if (ExpectSemi && 21111c94c16317c1a35c1549e022958188eea2567089Richard Smith ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) { 2112ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner // Skip to end of block or statement. 2113ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner SkipUntil(tok::r_brace, true, true); 2114ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner // If we stopped at a ';', eat it. 2115ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner if (Tok.is(tok::semi)) ConsumeToken(); 2116682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 21174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 21184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 211923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup.data(), 2120ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner DeclsInGroup.size()); 21214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 21224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 21237a614d8380297fcd2bc23986241905d97222948cRichard Smith/// ParseCXXMemberInitializer - Parse the brace-or-equal-initializer or 21247a614d8380297fcd2bc23986241905d97222948cRichard Smith/// pure-specifier. Also detect and reject any attempted defaulted/deleted 21257a614d8380297fcd2bc23986241905d97222948cRichard Smith/// function definition. The location of the '=', if any, will be placed in 21267a614d8380297fcd2bc23986241905d97222948cRichard Smith/// EqualLoc. 21277a614d8380297fcd2bc23986241905d97222948cRichard Smith/// 21287a614d8380297fcd2bc23986241905d97222948cRichard Smith/// pure-specifier: 21297a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '= 0' 213033deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// 21317a614d8380297fcd2bc23986241905d97222948cRichard Smith/// brace-or-equal-initializer: 21327a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '=' initializer-expression 213333deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// braced-init-list 213433deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// 21357a614d8380297fcd2bc23986241905d97222948cRichard Smith/// initializer-clause: 21367a614d8380297fcd2bc23986241905d97222948cRichard Smith/// assignment-expression 213733deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// braced-init-list 213833deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// 21397a614d8380297fcd2bc23986241905d97222948cRichard Smith/// defaulted/deleted function-definition: 21407a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '=' 'default' 21417a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '=' 'delete' 21427a614d8380297fcd2bc23986241905d97222948cRichard Smith/// 21437a614d8380297fcd2bc23986241905d97222948cRichard Smith/// Prior to C++0x, the assignment-expression in an initializer-clause must 21447a614d8380297fcd2bc23986241905d97222948cRichard Smith/// be a constant-expression. 2145552e29985a710f4ced62b39d70557501bd31ca9bDouglas GregorExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction, 21467a614d8380297fcd2bc23986241905d97222948cRichard Smith SourceLocation &EqualLoc) { 21477a614d8380297fcd2bc23986241905d97222948cRichard Smith assert((Tok.is(tok::equal) || Tok.is(tok::l_brace)) 21487a614d8380297fcd2bc23986241905d97222948cRichard Smith && "Data member initializer not starting with '=' or '{'"); 21497a614d8380297fcd2bc23986241905d97222948cRichard Smith 2150552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor EnterExpressionEvaluationContext Context(Actions, 2151552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor Sema::PotentiallyEvaluated, 2152552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor D); 21537a614d8380297fcd2bc23986241905d97222948cRichard Smith if (Tok.is(tok::equal)) { 21547a614d8380297fcd2bc23986241905d97222948cRichard Smith EqualLoc = ConsumeToken(); 21557a614d8380297fcd2bc23986241905d97222948cRichard Smith if (Tok.is(tok::kw_delete)) { 21567a614d8380297fcd2bc23986241905d97222948cRichard Smith // In principle, an initializer of '= delete p;' is legal, but it will 21577a614d8380297fcd2bc23986241905d97222948cRichard Smith // never type-check. It's better to diagnose it as an ill-formed expression 21587a614d8380297fcd2bc23986241905d97222948cRichard Smith // than as an ill-formed deleted non-function member. 21597a614d8380297fcd2bc23986241905d97222948cRichard Smith // An initializer of '= delete p, foo' will never be parsed, because 21607a614d8380297fcd2bc23986241905d97222948cRichard Smith // a top-level comma always ends the initializer expression. 21617a614d8380297fcd2bc23986241905d97222948cRichard Smith const Token &Next = NextToken(); 21627a614d8380297fcd2bc23986241905d97222948cRichard Smith if (IsFunction || Next.is(tok::semi) || Next.is(tok::comma) || 21637a614d8380297fcd2bc23986241905d97222948cRichard Smith Next.is(tok::eof)) { 21647a614d8380297fcd2bc23986241905d97222948cRichard Smith if (IsFunction) 21657a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) 21667a614d8380297fcd2bc23986241905d97222948cRichard Smith << 1 /* delete */; 21677a614d8380297fcd2bc23986241905d97222948cRichard Smith else 21687a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(ConsumeToken(), diag::err_deleted_non_function); 21697a614d8380297fcd2bc23986241905d97222948cRichard Smith return ExprResult(); 21707a614d8380297fcd2bc23986241905d97222948cRichard Smith } 21717a614d8380297fcd2bc23986241905d97222948cRichard Smith } else if (Tok.is(tok::kw_default)) { 21727a614d8380297fcd2bc23986241905d97222948cRichard Smith if (IsFunction) 21737a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(Tok, diag::err_default_delete_in_multiple_declaration) 21747a614d8380297fcd2bc23986241905d97222948cRichard Smith << 0 /* default */; 21757a614d8380297fcd2bc23986241905d97222948cRichard Smith else 21767a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(ConsumeToken(), diag::err_default_special_members); 21777a614d8380297fcd2bc23986241905d97222948cRichard Smith return ExprResult(); 21787a614d8380297fcd2bc23986241905d97222948cRichard Smith } 21797a614d8380297fcd2bc23986241905d97222948cRichard Smith 218033deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl } 218133deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl return ParseInitializer(); 21827a614d8380297fcd2bc23986241905d97222948cRichard Smith} 21837a614d8380297fcd2bc23986241905d97222948cRichard Smith 21844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition. 21854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 21864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-specification: 21874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declaration member-specification[opt] 21884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// access-specifier ':' member-specification[opt] 21894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 21904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidisvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, 2191d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall unsigned TagType, Decl *TagDecl) { 219231fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta assert((TagType == DeclSpec::TST_struct || 21934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis TagType == DeclSpec::TST_union || 219431fc07df7f0fc89ebf83ca05a20b29de45a7598dSanjiv Gupta TagType == DeclSpec::TST_class) && "Invalid TagType!"); 21954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 2196f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc, 2197f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall "parsing struct/union/class body"); 21981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 219926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // Determine whether this is a non-nested class. Note that local 220026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // classes are *not* considered to be nested classes. 220126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor bool NonNestedClass = true; 220226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (!ClassStack.empty()) { 220323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor for (const Scope *S = getCurScope(); S; S = S->getParent()) { 220426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (S->isClassScope()) { 220526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // We're inside a class scope, so this is a nested class. 220626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor NonNestedClass = false; 220726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor break; 220826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 220926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor 221026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if ((S->getFlags() & Scope::FnScope)) { 221126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // If we're in a function or function template declared in the 221226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // body of a class, then this is a local class rather than a 221326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // nested class. 221426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor const Scope *Parent = S->getParent(); 221526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (Parent->isTemplateParamScope()) 221626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor Parent = Parent->getParent(); 221726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (Parent->isClassScope()) 221826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor break; 221926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 222026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 222126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 22224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 22234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Enter a scope for the class. 22243218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope); 22254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 22266569d68745c8213709740337d2be52b031384f58Douglas Gregor // Note that we are parsing a new (potentially-nested) class definition. 222726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass); 22286569d68745c8213709740337d2be52b031384f58Douglas Gregor 2229ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor if (TagDecl) 223023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); 2231bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 2232b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson SourceLocation FinalLoc; 2233b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson 2234b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson // Parse the optional 'final' keyword. 22354e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) { 22368b11b5e6ce086fcaa7344bf84cffefcf4b53f9f6Richard Smith assert(isCXX0XFinalKeyword() && "not a class definition"); 22378b11b5e6ce086fcaa7344bf84cffefcf4b53f9f6Richard Smith FinalLoc = ConsumeToken(); 2238b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson 22394e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Diag(FinalLoc, getLangOpts().CPlusPlus0x ? 22407fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_override_control_keyword : 22417fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::ext_override_control_keyword) << "final"; 2242b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson } 2243cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 2244bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall if (Tok.is(tok::colon)) { 2245bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall ParseBaseClause(TagDecl); 2246bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 2247bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall if (!Tok.is(tok::l_brace)) { 2248bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall Diag(Tok, diag::err_expected_lbrace_after_base_specifiers); 2249db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall 2250db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall if (TagDecl) 225123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnTagDefinitionError(getCurScope(), TagDecl); 2252bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall return; 2253bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall } 2254bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall } 2255bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 2256bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall assert(Tok.is(tok::l_brace)); 22574a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_brace); 22584a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 2259bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 226042a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall if (TagDecl) 22612c3ee54e51d835a35bbf781c69e17f39e2ba0480Anders Carlsson Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc, 22624a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getOpenLocation()); 2263f9368159334ff86ea5fa367225c1a580977f3b03John McCall 22644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // C++ 11p3: Members of a class defined with the keyword class are private 22654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // by default. Members of a class defined with the keywords struct or union 22664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // are public by default. 22674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AccessSpecifier CurAS; 22684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (TagType == DeclSpec::TST_class) 22694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS_private; 22704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis else 22714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS_public; 22725f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParsedAttributes AccessAttrs(AttrFactory); 22734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 227407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (TagDecl) { 227507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // While we still have something to read, read the member-declarations. 227607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 227707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Each iteration of this loop reads one member-declaration. 227807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor 22794e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) || 2280563a645de82231a55e221fe655b7188bf8369662Francois Pichet Tok.is(tok::kw___if_not_exists))) { 2281563a645de82231a55e221fe655b7188bf8369662Francois Pichet ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS); 2282563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 2283563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 2284563a645de82231a55e221fe655b7188bf8369662Francois Pichet 228507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Check for extraneous top-level semicolon. 228607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (Tok.is(tok::semi)) { 228707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor Diag(Tok, diag::ext_extra_struct_semi) 228807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor << DeclSpec::getSpecifierName((DeclSpec::TST)TagType) 228907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor << FixItHint::CreateRemoval(Tok.getLocation()); 229007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor ConsumeToken(); 229107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor continue; 229207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } 22931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2294aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman if (Tok.is(tok::annot_pragma_vis)) { 2295aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman HandlePragmaVisibility(); 2296aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman continue; 2297aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman } 2298aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman 2299aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman if (Tok.is(tok::annot_pragma_pack)) { 2300aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman HandlePragmaPack(); 2301aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman continue; 2302aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman } 2303aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman 230407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor AccessSpecifier AS = getAccessSpecifierIfPresent(); 230507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (AS != AS_none) { 230607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Current token is a C++ access specifier. 230707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor CurAS = AS; 230807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor SourceLocation ASLoc = Tok.getLocation(); 230913f8daf70637f8f295134ac8e089dd7721e09085David Blaikie unsigned TokLength = Tok.getLength(); 231007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor ConsumeToken(); 23115f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen AccessAttrs.clear(); 23125f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen MaybeParseGNUAttributes(AccessAttrs); 23135f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen 231413f8daf70637f8f295134ac8e089dd7721e09085David Blaikie SourceLocation EndLoc; 231513f8daf70637f8f295134ac8e089dd7721e09085David Blaikie if (Tok.is(tok::colon)) { 231613f8daf70637f8f295134ac8e089dd7721e09085David Blaikie EndLoc = Tok.getLocation(); 231713f8daf70637f8f295134ac8e089dd7721e09085David Blaikie ConsumeToken(); 231813f8daf70637f8f295134ac8e089dd7721e09085David Blaikie } else if (Tok.is(tok::semi)) { 231913f8daf70637f8f295134ac8e089dd7721e09085David Blaikie EndLoc = Tok.getLocation(); 232013f8daf70637f8f295134ac8e089dd7721e09085David Blaikie ConsumeToken(); 232113f8daf70637f8f295134ac8e089dd7721e09085David Blaikie Diag(EndLoc, diag::err_expected_colon) 232213f8daf70637f8f295134ac8e089dd7721e09085David Blaikie << FixItHint::CreateReplacement(EndLoc, ":"); 232313f8daf70637f8f295134ac8e089dd7721e09085David Blaikie } else { 232413f8daf70637f8f295134ac8e089dd7721e09085David Blaikie EndLoc = ASLoc.getLocWithOffset(TokLength); 232513f8daf70637f8f295134ac8e089dd7721e09085David Blaikie Diag(EndLoc, diag::err_expected_colon) 232613f8daf70637f8f295134ac8e089dd7721e09085David Blaikie << FixItHint::CreateInsertion(EndLoc, ":"); 232713f8daf70637f8f295134ac8e089dd7721e09085David Blaikie } 2328c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen 2329c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen if (Actions.ActOnAccessSpecifier(AS, ASLoc, EndLoc, 2330c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen AccessAttrs.getList())) { 2331c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen // found another attribute than only annotations 2332c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen AccessAttrs.clear(); 2333c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen } 2334c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen 233507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor continue; 233607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } 23374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 233807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // FIXME: Make sure we don't have a template here. 23394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 234007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Parse all the comma separated declarators. 23415f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParseCXXClassMemberDeclaration(CurAS, AccessAttrs.getList()); 234207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } 23431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 23444a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 234507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } else { 234607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor SkipUntil(tok::r_brace, false, false); 23474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 23481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 23494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If attributes exist after class contents, parse them. 23500b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributes attrs(AttrFactory); 23517f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseGNUAttributes(attrs); 23524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 235342a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall if (TagDecl) 235423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl, 23554a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getOpenLocation(), 23564a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation(), 23577f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall attrs.getList()); 23584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 235974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // C++11 [class.mem]p2: 236074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Within the class member-specification, the class is regarded as complete 236174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // within function bodies, default arguments, exception-specifications, and 236274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // brace-or-equal-initializers for non-static data members (including such 236374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // things in nested classes). 236407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (TagDecl && NonNestedClass) { 23654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // We are not inside a nested class. This class and its nested classes 236672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // are complete and we can parse the delayed portions of method 2367eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // declarations and the lexed inline method definitions, along with any 2368eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // delayed attributes. 2369e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor SourceLocation SavedPrevTokLocation = PrevTokLocation; 2370eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski ParseLexedAttributes(getCurrentClass()); 23716569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseLexedMethodDeclarations(getCurrentClass()); 2372a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith 2373a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith // We've finished with all pending member declarations. 2374a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith Actions.ActOnFinishCXXMemberDecls(); 2375a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith 23767a614d8380297fcd2bc23986241905d97222948cRichard Smith ParseLexedMemberInitializers(getCurrentClass()); 23776569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseLexedMethodDefs(getCurrentClass()); 2378e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor PrevTokLocation = SavedPrevTokLocation; 23794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 23804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 238142a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall if (TagDecl) 23824a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, 23834a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 2384db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall 23854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Leave the class scope. 23866569d68745c8213709740337d2be52b031384f58Douglas Gregor ParsingDef.Pop(); 23878935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ClassScope.Exit(); 23884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 23897ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 23907ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer, 23917ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a 23927ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers 23937ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below: 23947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 23957ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code 23967ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { }; 23977ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base { 23987ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// int x; 23997ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// float f; 24007ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public: 24017ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// Derived(float f) : Base(), x(17), f(f) { } 24027ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// }; 24037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode 24047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 24051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++] ctor-initializer: 24061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ':' mem-initializer-list 24077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 24081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++] mem-initializer-list: 24093fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor/// mem-initializer ...[opt] 24103fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor/// mem-initializer ...[opt] , mem-initializer-list 2411d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseConstructorInitializer(Decl *ConstructorDecl) { 24127ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'"); 24137ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 241428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley // Poison the SEH identifiers so they are flagged as illegal in constructor initializers 241528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true); 24167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation ColonLoc = ConsumeToken(); 24171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 24185f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CXXCtorInitializer*, 4> MemInitializers; 24199db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor bool AnyErrors = false; 2420193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 24217ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor do { 24220133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor if (Tok.is(tok::code_completion)) { 24230133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor Actions.CodeCompleteConstructorInitializer(ConstructorDecl, 24240133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor MemInitializers.data(), 24250133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor MemInitializers.size()); 24267d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return cutOffParsing(); 24270133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor } else { 24280133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); 24290133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor if (!MemInit.isInvalid()) 24300133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor MemInitializers.push_back(MemInit.get()); 24310133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor else 24320133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor AnyErrors = true; 24330133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor } 24340133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor 24357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.is(tok::comma)) 24367ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor ConsumeToken(); 24377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor else if (Tok.is(tok::l_brace)) 24387ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor break; 2439b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor // If the next token looks like a base or member initializer, assume that 2440b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor // we're just missing a comma. 2441751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor else if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) { 2442751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation); 2443751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor Diag(Loc, diag::err_ctor_init_missing_comma) 2444751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor << FixItHint::CreateInsertion(Loc, ", "); 2445751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor } else { 24467ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Skip over garbage, until we get to '{'. Don't eat the '{'. 2447d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma); 24487ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SkipUntil(tok::l_brace, true, true); 24497ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor break; 24507ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 24517ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } while (true); 24527ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 24531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, 24549db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor MemInitializers.data(), MemInitializers.size(), 24559db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor AnyErrors); 24567ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor} 24577ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 24587ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is 24597ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one 24607ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See 24617ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example. 24627ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 24637ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer: 24647ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// mem-initializer-id '(' expression-list[opt] ')' 2465dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// [C++0x] mem-initializer-id braced-init-list 24661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 24677ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id: 24687ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// '::'[opt] nested-name-specifier[opt] class-name 24697ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// identifier 2470d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) { 2471bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian // parse '::'[opt] nested-name-specifier[opt] 2472bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian CXXScopeSpec SS; 2473efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 2474b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TemplateTypeTy; 2475961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian if (Tok.is(tok::annot_template_id)) { 247625a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 2477d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor if (TemplateId->Kind == TNK_Type_template || 2478d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor TemplateId->Kind == TNK_Dependent_template_name) { 2479059101f922de6eb765601459925f4c8914420b23Douglas Gregor AnnotateTemplateIdTokenAsType(); 2480961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); 2481b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall TemplateTypeTy = getTypeAnnotation(Tok); 2482961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian } 2483961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian } 2484f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // Uses of decltype will already have been converted to annot_decltype by 2485f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // ParseOptionalCXXScopeSpecifier at this point. 2486f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie if (!TemplateTypeTy && Tok.isNot(tok::identifier) 2487f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie && Tok.isNot(tok::annot_decltype)) { 24881ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_member_or_base_name); 24897ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor return true; 24907ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 24911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2492f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie IdentifierInfo *II = 0; 2493f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie DeclSpec DS(AttrFactory); 2494f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie SourceLocation IdLoc = Tok.getLocation(); 2495f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie if (Tok.is(tok::annot_decltype)) { 2496f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // Get the decltype expression, if there is one. 2497f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie ParseDecltypeSpecifier(DS); 2498f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie } else { 2499f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie if (Tok.is(tok::identifier)) 2500f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // Get the identifier. This may be a member name or a class name, 2501f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // but we'll let the semantic analysis determine which it is. 2502f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie II = Tok.getIdentifierInfo(); 2503f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie ConsumeToken(); 2504f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie } 2505f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie 25067ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 25077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Parse the '('. 25084e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) { 25097fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 25107fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 25116df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl ExprResult InitList = ParseBraceInitializer(); 25126df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl if (InitList.isInvalid()) 25136df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl return true; 25146df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl 25156df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl SourceLocation EllipsisLoc; 25166df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl if (Tok.is(tok::ellipsis)) 25176df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl EllipsisLoc = ConsumeToken(); 25186df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl 25196df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II, 2520f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie TemplateTypeTy, DS, IdLoc, 2521f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie InitList.take(), EllipsisLoc); 2522dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } else if(Tok.is(tok::l_paren)) { 25234a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 25244a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 2525dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl 2526dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl // Parse the optional expression-list. 2527dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl ExprVector ArgExprs(Actions); 2528dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl CommaLocsTy CommaLocs; 2529dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) { 2530dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl SkipUntil(tok::r_paren); 2531dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return true; 2532dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } 25337ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 25344a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 25357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 2536dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl SourceLocation EllipsisLoc; 2537dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (Tok.is(tok::ellipsis)) 2538dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl EllipsisLoc = ConsumeToken(); 25397ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 2540dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II, 2541f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie TemplateTypeTy, DS, IdLoc, 25424a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getOpenLocation(), ArgExprs.take(), 25434a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor ArgExprs.size(), T.getCloseLocation(), 2544dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl EllipsisLoc); 2545dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } 2546dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl 25474e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Diag(Tok, getLangOpts().CPlusPlus0x ? diag::err_expected_lparen_or_lbrace 2548dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl : diag::err_expected_lparen); 2549dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return true; 25507ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor} 25510fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 25527acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// \brief Parse a C++ exception-specification if present (C++0x [except.spec]). 25530fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 2554a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// exception-specification: 25557acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification 25567acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// noexcept-specification 25577acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 25587acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// noexcept-specification: 25597acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 'noexcept' 25607acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 'noexcept' '(' constant-expression ')' 25617acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType 256274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas GregorParser::tryParseExceptionSpecification(bool Delayed, 256374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor SourceRange &SpecificationRange, 25645f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<ParsedType> &DynamicExceptions, 25655f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<SourceRange> &DynamicExceptionRanges, 256674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor ExprResult &NoexceptExpr, 256774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor CachedTokens *&ExceptionSpecTokens) { 25687acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl ExceptionSpecificationType Result = EST_None; 256974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor ExceptionSpecTokens = 0; 257074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 257174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Handle delayed parsing of exception-specifications. 257274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor if (Delayed) { 257374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor if (Tok.isNot(tok::kw_throw) && Tok.isNot(tok::kw_noexcept)) 257474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor return EST_None; 257574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 257674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Consume and cache the starting token. 257774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor bool IsNoexcept = Tok.is(tok::kw_noexcept); 257874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor Token StartTok = Tok; 257974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor SpecificationRange = SourceRange(ConsumeToken()); 258074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 258174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Check for a '('. 258274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor if (!Tok.is(tok::l_paren)) { 258374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // If this is a bare 'noexcept', we're done. 258474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor if (IsNoexcept) { 258574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor Diag(Tok, diag::warn_cxx98_compat_noexcept_decl); 258674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor NoexceptExpr = 0; 258774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor return EST_BasicNoexcept; 258874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor } 258974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 259074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor Diag(Tok, diag::err_expected_lparen_after) << "throw"; 259174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor return EST_DynamicNone; 259274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor } 259374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 259474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Cache the tokens for the exception-specification. 259574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor ExceptionSpecTokens = new CachedTokens; 259674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor ExceptionSpecTokens->push_back(StartTok); // 'throw' or 'noexcept' 259774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor ExceptionSpecTokens->push_back(Tok); // '(' 259874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor SpecificationRange.setEnd(ConsumeParen()); // '(' 259974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 260074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor if (!ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens, 260174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor /*StopAtSemi=*/true, 260274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor /*ConsumeFinalToken=*/true)) { 260374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor NoexceptExpr = 0; 260474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor delete ExceptionSpecTokens; 260574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor ExceptionSpecTokens = 0; 260674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor return IsNoexcept? EST_BasicNoexcept : EST_DynamicNone; 260774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor } 260874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor SpecificationRange.setEnd(Tok.getLocation()); 260974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 261074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Add the 'stop' token. 261174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor Token End; 261274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor End.startToken(); 261374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor End.setKind(tok::cxx_exceptspec_end); 261474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor End.setLocation(Tok.getLocation()); 261574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor ExceptionSpecTokens->push_back(End); 261674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor return EST_Delayed; 261774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor } 261874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 26197acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // See if there's a dynamic specification. 26207acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.is(tok::kw_throw)) { 26217acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Result = ParseDynamicExceptionSpecification(SpecificationRange, 26227acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl DynamicExceptions, 26237acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl DynamicExceptionRanges); 26247acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl assert(DynamicExceptions.size() == DynamicExceptionRanges.size() && 26257acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl "Produced different number of exception types and ranges."); 26267acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 26277acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 26287acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // If there's no noexcept specification, we're done. 26297acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.isNot(tok::kw_noexcept)) 26307acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl return Result; 26317acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 2632841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith Diag(Tok, diag::warn_cxx98_compat_noexcept_decl); 2633841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith 26347acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // If we already had a dynamic specification, parse the noexcept for, 26357acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // recovery, but emit a diagnostic and don't store the results. 26367acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SourceRange NoexceptRange; 26377acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl ExceptionSpecificationType NoexceptType = EST_None; 26387acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 26397acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SourceLocation KeywordLoc = ConsumeToken(); 26407acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.is(tok::l_paren)) { 26417acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // There is an argument. 26424a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 26434a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 26447acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptType = EST_ComputedNoexcept; 26457acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptExpr = ParseConstantExpression(); 264660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // The argument must be contextually convertible to bool. We use 264760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // ActOnBooleanCondition for this purpose. 264860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (!NoexceptExpr.isInvalid()) 264960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NoexceptExpr = Actions.ActOnBooleanCondition(getCurScope(), KeywordLoc, 265060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NoexceptExpr.get()); 26514a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 26524a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation()); 26537acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } else { 26547acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // There is no argument. 26557acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptType = EST_BasicNoexcept; 26567acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptRange = SourceRange(KeywordLoc, KeywordLoc); 26577acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 26587acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 26597acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Result == EST_None) { 26607acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SpecificationRange = NoexceptRange; 26617acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Result = NoexceptType; 26627acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 26637acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // If there's a dynamic specification after a noexcept specification, 26647acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // parse that and ignore the results. 26657acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.is(tok::kw_throw)) { 26667acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification); 26677acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions, 26687acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl DynamicExceptionRanges); 26697acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 26707acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } else { 26717acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification); 26727acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 26737acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 26747acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl return Result; 26757acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl} 26767acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 26777acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// ParseDynamicExceptionSpecification - Parse a C++ 26787acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification (C++ [except.spec]). 26797acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 26807acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification: 2681a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// 'throw' '(' type-id-list [opt] ')' 2682a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS] 'throw' '(' '...' ')' 26831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 2684a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// type-id-list: 2685a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor/// type-id ... [opt] 2686a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor/// type-id-list ',' type-id ... [opt] 26870fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 26887acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType Parser::ParseDynamicExceptionSpecification( 26897acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SourceRange &SpecificationRange, 26905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<ParsedType> &Exceptions, 26915f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<SourceRange> &Ranges) { 26920fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor assert(Tok.is(tok::kw_throw) && "expected throw"); 26931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26947acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SpecificationRange.setBegin(ConsumeToken()); 26954a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 26964a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.consumeOpen()) { 26977acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Diag(Tok, diag::err_expected_lparen_after) << "throw"; 26987acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SpecificationRange.setEnd(SpecificationRange.getBegin()); 269960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return EST_DynamicNone; 27000fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor } 27010fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 2702a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor // Parse throw(...), a Microsoft extension that means "this function 2703a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor // can throw anything". 2704a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor if (Tok.is(tok::ellipsis)) { 2705a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor SourceLocation EllipsisLoc = ConsumeToken(); 27064e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().MicrosoftExt) 2707a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec); 27084a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 27094a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SpecificationRange.setEnd(T.getCloseLocation()); 271060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return EST_MSAny; 2711a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor } 2712a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor 27130fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor // Parse the sequence of type-ids. 2714ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl SourceRange Range; 27150fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor while (Tok.isNot(tok::r_paren)) { 2716ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl TypeResult Res(ParseTypeName(&Range)); 27177acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 2718a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor if (Tok.is(tok::ellipsis)) { 2719a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor // C++0x [temp.variadic]p5: 2720a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor // - In a dynamic-exception-specification (15.4); the pattern is a 2721a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor // type-id. 2722a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor SourceLocation Ellipsis = ConsumeToken(); 27237acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Range.setEnd(Ellipsis); 2724a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor if (!Res.isInvalid()) 2725a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor Res = Actions.ActOnPackExpansion(Res.get(), Ellipsis); 2726a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor } 27277acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 2728ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl if (!Res.isInvalid()) { 27297dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl Exceptions.push_back(Res.get()); 2730ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl Ranges.push_back(Range); 2731ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl } 2732a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor 27330fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor if (Tok.is(tok::comma)) 27340fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor ConsumeToken(); 27357dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl else 27360fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor break; 27370fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor } 27380fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 27394a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 27404a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SpecificationRange.setEnd(T.getCloseLocation()); 274160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic; 27420fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor} 27436569d68745c8213709740337d2be52b031384f58Douglas Gregor 2744dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// ParseTrailingReturnType - Parse a trailing return type on a new-style 2745dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// function declaration. 2746ae7902c4293d9de8b9591759513f0d075f45022aDouglas GregorTypeResult Parser::ParseTrailingReturnType(SourceRange &Range) { 2747dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor assert(Tok.is(tok::arrow) && "expected arrow"); 2748dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor 2749dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor ConsumeToken(); 2750dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor 27517796eb5643244f3134834253ce5ea89107ac21c1Richard Smith return ParseTypeName(&Range, Declarator::TrailingReturnContext); 2752dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor} 2753dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor 27546569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief We have just started parsing the definition of a new class, 27556569d68745c8213709740337d2be52b031384f58Douglas Gregor/// so push that class onto our stack of classes that is currently 27566569d68745c8213709740337d2be52b031384f58Douglas Gregor/// being parsed. 2757eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallSema::ParsingClassState 2758eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallParser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass) { 275926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor assert((NonNestedClass || !ClassStack.empty()) && 27606569d68745c8213709740337d2be52b031384f58Douglas Gregor "Nested class without outer class"); 276126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass)); 2762eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall return Actions.PushParsingClass(); 27636569d68745c8213709740337d2be52b031384f58Douglas Gregor} 27646569d68745c8213709740337d2be52b031384f58Douglas Gregor 27656569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Deallocate the given parsed class and all of its nested 27666569d68745c8213709740337d2be52b031384f58Douglas Gregor/// classes. 27676569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) { 2768d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I) 2769d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor delete Class->LateParsedDeclarations[I]; 27706569d68745c8213709740337d2be52b031384f58Douglas Gregor delete Class; 27716569d68745c8213709740337d2be52b031384f58Douglas Gregor} 27726569d68745c8213709740337d2be52b031384f58Douglas Gregor 27736569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Pop the top class of the stack of classes that are 27746569d68745c8213709740337d2be52b031384f58Douglas Gregor/// currently being parsed. 27756569d68745c8213709740337d2be52b031384f58Douglas Gregor/// 27766569d68745c8213709740337d2be52b031384f58Douglas Gregor/// This routine should be called when we have finished parsing the 27776569d68745c8213709740337d2be52b031384f58Douglas Gregor/// definition of a class, but have not yet popped the Scope 27786569d68745c8213709740337d2be52b031384f58Douglas Gregor/// associated with the class's definition. 27796569d68745c8213709740337d2be52b031384f58Douglas Gregor/// 27806569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \returns true if the class we've popped is a top-level class, 27816569d68745c8213709740337d2be52b031384f58Douglas Gregor/// false otherwise. 2782eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Parser::PopParsingClass(Sema::ParsingClassState state) { 27836569d68745c8213709740337d2be52b031384f58Douglas Gregor assert(!ClassStack.empty() && "Mismatched push/pop for class parsing"); 27841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2785eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall Actions.PopParsingClass(state); 2786eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 27876569d68745c8213709740337d2be52b031384f58Douglas Gregor ParsingClass *Victim = ClassStack.top(); 27886569d68745c8213709740337d2be52b031384f58Douglas Gregor ClassStack.pop(); 27896569d68745c8213709740337d2be52b031384f58Douglas Gregor if (Victim->TopLevelClass) { 27906569d68745c8213709740337d2be52b031384f58Douglas Gregor // Deallocate all of the nested classes of this class, 27916569d68745c8213709740337d2be52b031384f58Douglas Gregor // recursively: we don't need to keep any of this information. 27926569d68745c8213709740337d2be52b031384f58Douglas Gregor DeallocateParsedClasses(Victim); 27936569d68745c8213709740337d2be52b031384f58Douglas Gregor return; 27941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 27956569d68745c8213709740337d2be52b031384f58Douglas Gregor assert(!ClassStack.empty() && "Missing top-level class?"); 27966569d68745c8213709740337d2be52b031384f58Douglas Gregor 2797d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (Victim->LateParsedDeclarations.empty()) { 27986569d68745c8213709740337d2be52b031384f58Douglas Gregor // The victim is a nested class, but we will not need to perform 27996569d68745c8213709740337d2be52b031384f58Douglas Gregor // any processing after the definition of this class since it has 28006569d68745c8213709740337d2be52b031384f58Douglas Gregor // no members whose handling was delayed. Therefore, we can just 28016569d68745c8213709740337d2be52b031384f58Douglas Gregor // remove this nested class. 2802d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor DeallocateParsedClasses(Victim); 28036569d68745c8213709740337d2be52b031384f58Douglas Gregor return; 28046569d68745c8213709740337d2be52b031384f58Douglas Gregor } 28056569d68745c8213709740337d2be52b031384f58Douglas Gregor 28066569d68745c8213709740337d2be52b031384f58Douglas Gregor // This nested class has some members that will need to be processed 28076569d68745c8213709740337d2be52b031384f58Douglas Gregor // after the top-level class is completely defined. Therefore, add 28086569d68745c8213709740337d2be52b031384f58Douglas Gregor // it to the list of nested classes within its parent. 280923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor assert(getCurScope()->isClassScope() && "Nested class outside of class scope?"); 2810d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ClassStack.top()->LateParsedDeclarations.push_back(new LateParsedClass(this, Victim)); 281123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope(); 28126569d68745c8213709740337d2be52b031384f58Douglas Gregor} 2813bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2814c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// \brief Try to parse an 'identifier' which appears within an attribute-token. 2815c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// 2816c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// \return the parsed identifier on success, and 0 if the next token is not an 2817c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute-token. 2818c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// 2819c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// C++11 [dcl.attr.grammar]p3: 2820c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// If a keyword or an alternative token that satisfies the syntactic 2821c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// requirements of an identifier is contained in an attribute-token, 2822c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// it is considered an identifier. 2823c56298d87a9df507805a548d7d515e8b511df2c0Richard SmithIdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(SourceLocation &Loc) { 2824c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith switch (Tok.getKind()) { 2825c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith default: 2826c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // Identifiers and keywords have identifier info attached. 2827c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (IdentifierInfo *II = Tok.getIdentifierInfo()) { 2828c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith Loc = ConsumeToken(); 2829c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith return II; 2830c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 2831c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith return 0; 2832c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 2833c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::ampamp: // 'and' 2834c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::pipe: // 'bitor' 2835c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::pipepipe: // 'or' 2836c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::caret: // 'xor' 2837c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::tilde: // 'compl' 2838c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::amp: // 'bitand' 2839c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::ampequal: // 'and_eq' 2840c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::pipeequal: // 'or_eq' 2841c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::caretequal: // 'xor_eq' 2842c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::exclaim: // 'not' 2843c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::exclaimequal: // 'not_eq' 2844c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // Alternative tokens do not have identifier info, but their spelling 2845c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // starts with an alphabetical character. 2846c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith llvm::SmallString<8> SpellingBuf; 2847c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith StringRef Spelling = PP.getSpelling(Tok.getLocation(), SpellingBuf); 2848c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (std::isalpha(Spelling[0])) { 2849c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith Loc = ConsumeToken(); 28500eb7526cd2524af78fb9a2a2522045fb25fc3d27Benjamin Kramer return &PP.getIdentifierTable().get(Spelling); 2851c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 2852c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith return 0; 2853c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 2854c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith} 2855c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 2856c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier. Currently 28573497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// only parses standard attributes. 2858bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28596ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-specifier: 2860bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '[' '[' attribute-list ']' ']' 286182d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne/// alignment-specifier 2862bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28636ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-list: 2864bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute[opt] 2865bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-list ',' attribute[opt] 2866c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute '...' 2867c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute-list ',' attribute '...' 2868bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28696ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute: 2870bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-token attribute-argument-clause[opt] 2871bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28726ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-token: 2873bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// identifier 2874bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-scoped-token 2875bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28766ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-scoped-token: 2877bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-namespace '::' identifier 2878bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28796ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-namespace: 2880bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// identifier 2881bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28826ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-argument-clause: 2883bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '(' balanced-token-seq ')' 2884bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28856ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] balanced-token-seq: 2886bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// balanced-token 2887bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// balanced-token-seq balanced-token 2888bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28896ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] balanced-token: 2890bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '(' balanced-token-seq ')' 2891bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '[' balanced-token-seq ']' 2892bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '{' balanced-token-seq '}' 2893bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// any token but '(', ')', '[', ']', '{', or '}' 2894c56298d87a9df507805a548d7d515e8b511df2c0Richard Smithvoid Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs, 28953497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne SourceLocation *endLoc) { 289682d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne if (Tok.is(tok::kw_alignas)) { 289741be673e93ed225b45479557b20ff19b3082bae8Richard Smith Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas); 289882d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne ParseAlignmentSpecifier(attrs, endLoc); 289982d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne return; 290082d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne } 290182d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne 2902bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square) 29036ee326af4e77e6f05973486097884d7431f2108dRichard Smith && "Not a C++11 attribute list"); 2904bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 290541be673e93ed225b45479557b20ff19b3082bae8Richard Smith Diag(Tok.getLocation(), diag::warn_cxx98_compat_attribute); 290641be673e93ed225b45479557b20ff19b3082bae8Richard Smith 2907bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeBracket(); 2908bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeBracket(); 2909193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 2910c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith while (Tok.isNot(tok::r_square)) { 2911bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // attribute not present 2912bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.is(tok::comma)) { 2913bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeToken(); 2914bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt continue; 2915bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2916bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2917c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith SourceLocation ScopeLoc, AttrLoc; 2918c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith IdentifierInfo *ScopeName = 0, *AttrName = 0; 2919c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 2920c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith AttrName = TryParseCXX11AttributeIdentifier(AttrLoc); 2921c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (!AttrName) 2922c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // Break out to the "expected ']'" diagnostic. 2923c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith break; 2924193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 2925bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // scoped attribute 2926bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.is(tok::coloncolon)) { 2927bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeToken(); 2928bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2929c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith ScopeName = AttrName; 2930c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith ScopeLoc = AttrLoc; 2931c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 2932c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith AttrName = TryParseCXX11AttributeIdentifier(AttrLoc); 2933c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (!AttrName) { 2934bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt Diag(Tok.getLocation(), diag::err_expected_ident); 2935bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_square, tok::comma, true, true); 2936bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt continue; 2937bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2938bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2939bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2940bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt bool AttrParsed = false; 2941bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // No scoped names are supported; ideally we could put all non-standard 2942bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // attributes into namespaces. 2943bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!ScopeName) { 29446ee326af4e77e6f05973486097884d7431f2108dRichard Smith switch (AttributeList::getKind(AttrName)) { 2945bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // No arguments 29467725e67639fa2fe74f8775b7ed884a076ffdbffcSean Hunt case AttributeList::AT_carries_dependency: 294715e14a289583616e582a23b320933e846a742626Anders Carlsson case AttributeList::AT_noreturn: { 2948bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.is(tok::l_paren)) { 2949c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith Diag(Tok.getLocation(), diag::err_cxx11_attribute_forbids_arguments) 2950bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt << AttrName->getName(); 2951bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt break; 2952bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2953bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 29540b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall attrs.addNew(AttrName, AttrLoc, 0, AttrLoc, 0, 29550b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall SourceLocation(), 0, 0, false, true); 2956bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt AttrParsed = true; 2957bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt break; 2958bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2959bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2960bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // Silence warnings 2961bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt default: break; 2962bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2963bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2964bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2965bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // Skip the entire parameter clause, if any 2966bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!AttrParsed && Tok.is(tok::l_paren)) { 2967bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeParen(); 2968bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // SkipUntil maintains the balancedness of tokens. 2969bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_paren, false); 2970bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 29716ee326af4e77e6f05973486097884d7431f2108dRichard Smith 2972c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (Tok.is(tok::ellipsis)) { 2973c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (AttrParsed) 2974c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) 2975c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith << AttrName->getName(); 29766ee326af4e77e6f05973486097884d7431f2108dRichard Smith ConsumeToken(); 2977c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 2978bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2979bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2980bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare)) 2981bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_square, false); 29823497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne if (endLoc) 29833497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne *endLoc = Tok.getLocation(); 2984bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare)) 2985bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_square, false); 29863497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne} 29873497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne 2988c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// ParseCXX11Attributes - Parse a C++0x attribute-specifier-seq. 29893497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// 29903497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// attribute-specifier-seq: 29913497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// attribute-specifier-seq[opt] attribute-specifier 2992c56298d87a9df507805a548d7d515e8b511df2c0Richard Smithvoid Parser::ParseCXX11Attributes(ParsedAttributesWithRange &attrs, 29933497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne SourceLocation *endLoc) { 29943497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne SourceLocation StartLoc = Tok.getLocation(), Loc; 29953497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne if (!endLoc) 29963497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne endLoc = &Loc; 29973497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne 29988828ee7faa42f889ade3bb635dc5f1338be671b1Douglas Gregor do { 2999c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith ParseCXX11AttributeSpecifier(attrs, endLoc); 30006ee326af4e77e6f05973486097884d7431f2108dRichard Smith } while (isCXX11AttributeSpecifier()); 3001bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 30023497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne attrs.Range = SourceRange(StartLoc, *endLoc); 3003bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 3004bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 3005334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ParseMicrosoftAttributes - Parse a Microsoft attribute [Attr] 3006334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// 3007334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute: 3008334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// '[' token-seq ']' 3009334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// 3010334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute-seq: 3011334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ms-attribute[opt] 3012334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ms-attribute ms-attribute-seq 30137f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCallvoid Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs, 30147f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall SourceLocation *endLoc) { 3015334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list"); 3016334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet 3017334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet while (Tok.is(tok::l_square)) { 30186ee326af4e77e6f05973486097884d7431f2108dRichard Smith // FIXME: If this is actually a C++11 attribute, parse it as one. 3019334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet ConsumeBracket(); 3020334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet SkipUntil(tok::r_square, true, true); 30217f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (endLoc) *endLoc = Tok.getLocation(); 3022334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); 3023334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet } 3024334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet} 3025563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3026563a645de82231a55e221fe655b7188bf8369662Francois Pichetvoid Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType, 3027563a645de82231a55e221fe655b7188bf8369662Francois Pichet AccessSpecifier& CurAS) { 30283896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor IfExistsCondition Result; 3029563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (ParseMicrosoftIfExistsCondition(Result)) 3030563a645de82231a55e221fe655b7188bf8369662Francois Pichet return; 3031563a645de82231a55e221fe655b7188bf8369662Francois Pichet 30323896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor BalancedDelimiterTracker Braces(*this, tok::l_brace); 30333896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor if (Braces.consumeOpen()) { 3034563a645de82231a55e221fe655b7188bf8369662Francois Pichet Diag(Tok, diag::err_expected_lbrace); 3035563a645de82231a55e221fe655b7188bf8369662Francois Pichet return; 3036563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3037563a645de82231a55e221fe655b7188bf8369662Francois Pichet 30383896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor switch (Result.Behavior) { 30393896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor case IEB_Parse: 30403896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor // Parse the declarations below. 30413896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor break; 30423896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor 30433896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor case IEB_Dependent: 30443896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists) 30453896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor << Result.IsIfExists; 30463896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor // Fall through to skip. 30473896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor 30483896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor case IEB_Skip: 30493896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor Braces.skipToEnd(); 3050563a645de82231a55e221fe655b7188bf8369662Francois Pichet return; 3051563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3052563a645de82231a55e221fe655b7188bf8369662Francois Pichet 30533896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 3054563a645de82231a55e221fe655b7188bf8369662Francois Pichet // __if_exists, __if_not_exists can nest. 3055563a645de82231a55e221fe655b7188bf8369662Francois Pichet if ((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists))) { 3056563a645de82231a55e221fe655b7188bf8369662Francois Pichet ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS); 3057563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 3058563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3059563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3060563a645de82231a55e221fe655b7188bf8369662Francois Pichet // Check for extraneous top-level semicolon. 3061563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (Tok.is(tok::semi)) { 3062563a645de82231a55e221fe655b7188bf8369662Francois Pichet Diag(Tok, diag::ext_extra_struct_semi) 3063563a645de82231a55e221fe655b7188bf8369662Francois Pichet << DeclSpec::getSpecifierName((DeclSpec::TST)TagType) 3064563a645de82231a55e221fe655b7188bf8369662Francois Pichet << FixItHint::CreateRemoval(Tok.getLocation()); 3065563a645de82231a55e221fe655b7188bf8369662Francois Pichet ConsumeToken(); 3066563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 3067563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3068563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3069563a645de82231a55e221fe655b7188bf8369662Francois Pichet AccessSpecifier AS = getAccessSpecifierIfPresent(); 3070563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (AS != AS_none) { 3071563a645de82231a55e221fe655b7188bf8369662Francois Pichet // Current token is a C++ access specifier. 3072563a645de82231a55e221fe655b7188bf8369662Francois Pichet CurAS = AS; 3073563a645de82231a55e221fe655b7188bf8369662Francois Pichet SourceLocation ASLoc = Tok.getLocation(); 3074563a645de82231a55e221fe655b7188bf8369662Francois Pichet ConsumeToken(); 3075563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (Tok.is(tok::colon)) 3076563a645de82231a55e221fe655b7188bf8369662Francois Pichet Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation()); 3077563a645de82231a55e221fe655b7188bf8369662Francois Pichet else 3078563a645de82231a55e221fe655b7188bf8369662Francois Pichet Diag(Tok, diag::err_expected_colon); 3079563a645de82231a55e221fe655b7188bf8369662Francois Pichet ConsumeToken(); 3080563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 3081563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3082563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3083563a645de82231a55e221fe655b7188bf8369662Francois Pichet // Parse all the comma separated declarators. 30845f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParseCXXClassMemberDeclaration(CurAS, 0); 3085563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 30863896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor 30873896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor Braces.consumeClose(); 3088563a645de82231a55e221fe655b7188bf8369662Francois Pichet} 3089