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; 4472edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ParsedAttributesWithRange attrs(AttrFactory); 4482edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 4492edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt // FIXME: Simply skip the attributes and diagnose, don't bother parsing them. 4502edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt MaybeParseCXX0XAttributes(attrs); 4512edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 4522edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt attrs.clear(); 4532edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt attrs.Range = SourceRange(); 4549cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 4559cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Ignore optional 'typename'. 45612c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor // FIXME: This is wrong; we should parse this as a typename-specifier. 4579cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (Tok.is(tok::kw_typename)) { 4587ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall TypenameLoc = Tok.getLocation(); 4599cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor ConsumeToken(); 4609cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor IsTypeName = true; 4619cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 4629cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor else 4639cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor IsTypeName = false; 4649cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 4659cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Parse nested-name-specifier. 466efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 4679cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 4689cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Check nested-name specifier. 4699cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (SS.isInvalid()) { 4709cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SkipUntil(tok::semi); 471d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 4729cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 4731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 474193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // Parse the unqualified-id. We allow parsing of both constructor and 47512c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor // destructor names and allow the action module to diagnose any semantic 47612c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor // errors. 477e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara SourceLocation TemplateKWLoc; 47812c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor UnqualifiedId Name; 479193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam if (ParseUnqualifiedId(SS, 48012c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor /*EnteringContext=*/false, 48112c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor /*AllowDestructorName=*/true, 482193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam /*AllowConstructorName=*/true, 483b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType(), 484e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara TemplateKWLoc, 48512c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor Name)) { 4869cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SkipUntil(tok::semi); 487d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 4889cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 489193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 4902edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt MaybeParseCXX0XAttributes(attrs); 491162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 492162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Maybe this is an alias-declaration. 493162e1c1b487352434552147967c3dd296ebee2f7Richard Smith bool IsAliasDecl = Tok.is(tok::equal); 494162e1c1b487352434552147967c3dd296ebee2f7Richard Smith TypeResult TypeAlias; 495162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (IsAliasDecl) { 4963e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // TODO: Attribute support. C++0x attributes may appear before the equals. 4973e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // Where can GNU attributes appear? 498162e1c1b487352434552147967c3dd296ebee2f7Richard Smith ConsumeToken(); 499162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 5004e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Diag(Tok.getLocation(), getLangOpts().CPlusPlus0x ? 5017fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_alias_declaration : 5027fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::ext_alias_declaration); 503162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 5043e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // Type alias templates cannot be specialized. 5053e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith int SpecKind = -1; 506536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith if (TemplateInfo.Kind == ParsedTemplateInfo::Template && 507536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith Name.getKind() == UnqualifiedId::IK_TemplateId) 5083e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SpecKind = 0; 5093e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization) 5103e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SpecKind = 1; 5113e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) 5123e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SpecKind = 2; 5133e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (SpecKind != -1) { 5143e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SourceRange Range; 5153e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (SpecKind == 0) 5163e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Range = SourceRange(Name.TemplateId->LAngleLoc, 5173e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Name.TemplateId->RAngleLoc); 5183e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith else 5193e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Range = TemplateInfo.getSourceRange(); 5203e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Diag(Range.getBegin(), diag::err_alias_declaration_specialization) 5213e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith << SpecKind << Range; 5223e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SkipUntil(tok::semi); 5233e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return 0; 5243e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 5253e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith 526162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Name must be an identifier. 527162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (Name.getKind() != UnqualifiedId::IK_Identifier) { 528162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Diag(Name.StartLocation, diag::err_alias_declaration_not_identifier); 529162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // No removal fixit: can't recover from this. 530162e1c1b487352434552147967c3dd296ebee2f7Richard Smith SkipUntil(tok::semi); 531162e1c1b487352434552147967c3dd296ebee2f7Richard Smith return 0; 532162e1c1b487352434552147967c3dd296ebee2f7Richard Smith } else if (IsTypeName) 533162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Diag(TypenameLoc, diag::err_alias_declaration_not_identifier) 534162e1c1b487352434552147967c3dd296ebee2f7Richard Smith << FixItHint::CreateRemoval(SourceRange(TypenameLoc, 535162e1c1b487352434552147967c3dd296ebee2f7Richard Smith SS.isNotEmpty() ? SS.getEndLoc() : TypenameLoc)); 536162e1c1b487352434552147967c3dd296ebee2f7Richard Smith else if (SS.isNotEmpty()) 537162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier) 538162e1c1b487352434552147967c3dd296ebee2f7Richard Smith << FixItHint::CreateRemoval(SS.getRange()); 539162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 5403e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TypeAlias = ParseTypeName(0, TemplateInfo.Kind ? 5413e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Declarator::AliasTemplateContext : 542cdda47faab5c2c61c239491a1a091e071ed3e38eJohn McCall Declarator::AliasDeclContext, AS, OwnedType); 5432edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt } else { 5442edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt // C++11 attributes are not allowed on a using-declaration, but GNU ones 5452edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt // are. 5462edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 5472edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 548162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Parse (optional) attributes (most likely GNU strong-using extension). 549162e1c1b487352434552147967c3dd296ebee2f7Richard Smith MaybeParseGNUAttributes(attrs); 5502edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt } 5511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5529cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Eat ';'. 5539cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor DeclEnd = Tok.getLocation(); 5549cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor ExpectAndConsume(tok::semi, diag::err_expected_semi_after, 555162e1c1b487352434552147967c3dd296ebee2f7Richard Smith !attrs.empty() ? "attributes list" : 556162e1c1b487352434552147967c3dd296ebee2f7Richard Smith IsAliasDecl ? "alias declaration" : "using declaration", 55712c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor tok::semi); 5589cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 55978b810559d89e996e00684335407443936ce34a1John McCall // Diagnose an attempt to declare a templated using-declaration. 5603e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // In C++0x, alias-declarations can be templates: 561162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // template <...> using id = type; 5623e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (TemplateInfo.Kind && !IsAliasDecl) { 56378b810559d89e996e00684335407443936ce34a1John McCall SourceRange R = TemplateInfo.getSourceRange(); 56478b810559d89e996e00684335407443936ce34a1John McCall Diag(UsingLoc, diag::err_templated_using_declaration) 56578b810559d89e996e00684335407443936ce34a1John McCall << R << FixItHint::CreateRemoval(R); 56678b810559d89e996e00684335407443936ce34a1John McCall 56778b810559d89e996e00684335407443936ce34a1John McCall // Unfortunately, we have to bail out instead of recovering by 56878b810559d89e996e00684335407443936ce34a1John McCall // ignoring the parameters, just in case the nested name specifier 56978b810559d89e996e00684335407443936ce34a1John McCall // depends on the parameters. 57078b810559d89e996e00684335407443936ce34a1John McCall return 0; 57178b810559d89e996e00684335407443936ce34a1John McCall } 57278b810559d89e996e00684335407443936ce34a1John McCall 573480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor // "typename" keyword is allowed for identifiers only, 574480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor // because it may be a type definition. 575480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor if (IsTypeName && Name.getKind() != UnqualifiedId::IK_Identifier) { 576480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor Diag(Name.getSourceRange().getBegin(), diag::err_typename_identifiers_only) 577480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor << FixItHint::CreateRemoval(SourceRange(TypenameLoc)); 578480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor // Proceed parsing, but reset the IsTypeName flag. 579480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor IsTypeName = false; 580480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor } 581480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor 5823e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (IsAliasDecl) { 5833e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams; 5845354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer MultiTemplateParamsArg TemplateParamsArg( 5853e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TemplateParams ? TemplateParams->data() : 0, 5863e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TemplateParams ? TemplateParams->size() : 0); 5872edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt // FIXME: Propagate attributes. 5883e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg, 5893e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith UsingLoc, Name, TypeAlias); 5903e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 591162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 5928113ecfa4e41e2c888b1794389dfe3bce6386493Ted Kremenek return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS, 5937f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall Name, attrs.getList(), 5947f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall IsTypeName, TypenameLoc); 595f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 596f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 597ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer/// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration. 598511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// 599c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// [C++0x] static_assert-declaration: 600c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// static_assert ( constant-expression , string-literal ) ; 601c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// 602ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer/// [C11] static_assert-declaration: 603c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// _Static_assert ( constant-expression , string-literal ) ; 604511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// 605d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){ 606c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne assert((Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) && 607c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne "Not a static_assert declaration"); 608c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne 6094e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11) 610ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer Diag(Tok, diag::ext_c11_static_assert); 611841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith if (Tok.is(tok::kw_static_assert)) 612841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith Diag(Tok, diag::warn_cxx98_compat_static_assert); 613c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne 614511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson SourceLocation StaticAssertLoc = ConsumeToken(); 6151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6164a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 6174a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.consumeOpen()) { 618511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson Diag(Tok, diag::err_expected_lparen); 619d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 620511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 6211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 62260d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AssertExpr(ParseConstantExpression()); 623511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson if (AssertExpr.isInvalid()) { 624511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson SkipUntil(tok::semi); 625d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 626511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 6271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 628ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi)) 629d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 630ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson 6310cc323c6bed7206f9743a9775ec8d9cb90655f9cRichard Smith if (!isTokenStringLiteral()) { 632511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson Diag(Tok, diag::err_expected_string_literal); 633511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson SkipUntil(tok::semi); 634d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 635511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 6361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 63760d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AssertMessage(ParseStringLiteralExpression()); 63899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith if (AssertMessage.isInvalid()) { 63999831e4677a7e2e051af636221694d60ba31fcdbRichard Smith SkipUntil(tok::semi); 640d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 64199831e4677a7e2e051af636221694d60ba31fcdbRichard Smith } 642511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 6434a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 6441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 64597144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner DeclEnd = Tok.getLocation(); 6469ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert); 647511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 6489ae2f076ca5ab1feb3ba95629099ec2319833701John McCall return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, 6499ae2f076ca5ab1feb3ba95629099ec2319833701John McCall AssertExpr.take(), 650a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara AssertMessage.take(), 6514a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 652511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson} 653511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 6546fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// ParseDecltypeSpecifier - Parse a C++0x decltype specifier. 6556fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 6566fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 'decltype' ( expression ) 6576fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 65842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid BlaikieSourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) { 65942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie assert((Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) 66042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie && "Not a decltype specifier"); 66142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 6626fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson 66342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie ExprResult Result; 66442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation StartLoc = Tok.getLocation(); 66542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation EndLoc; 6661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 66742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Tok.is(tok::annot_decltype)) { 66842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Result = getExprAnnotation(Tok); 66942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie EndLoc = Tok.getAnnotationEndLoc(); 67042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie ConsumeToken(); 67142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Result.isInvalid()) { 67242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 67342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return EndLoc; 67442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 67542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } else { 676c7b5543ad32a5c265c02e71b2a6f9856440ed13fRichard Smith if (Tok.getIdentifierInfo()->isStr("decltype")) 677c7b5543ad32a5c265c02e71b2a6f9856440ed13fRichard Smith Diag(Tok, diag::warn_cxx98_compat_decltype); 67839304fad1c8a7b7e64121e9ae544b18e460b682cRichard Smith 67942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie ConsumeToken(); 6801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 68142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie BalancedDelimiterTracker T(*this, tok::l_paren); 68242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (T.expectAndConsume(diag::err_expected_lparen_after, 68342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie "decltype", tok::r_paren)) { 68442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 68542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return T.getOpenLocation() == Tok.getLocation() ? 68642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie StartLoc : T.getOpenLocation(); 68742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 6881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 68942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // Parse the expression 69042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 69142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // C++0x [dcl.type.simple]p4: 69242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // The operand of the decltype specifier is an unevaluated operand. 69376f3f69db1416425070177243e9f390122c553e0Richard Smith EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, 69476f3f69db1416425070177243e9f390122c553e0Richard Smith 0, /*IsDecltype=*/true); 69542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Result = ParseExpression(); 69642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Result.isInvalid()) { 697d8e4daca4a44d25a9c09d51def9e3d485d4f302cRichard Smith SkipUntil(tok::r_paren); 69842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 699d8e4daca4a44d25a9c09d51def9e3d485d4f302cRichard Smith return StartLoc; 70042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 70142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 70242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // Match the ')' 70342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie T.consumeClose(); 70442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (T.getCloseLocation().isInvalid()) { 70542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 70642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // FIXME: this should return the location of the last token 70742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // that was consumed (by "consumeClose()") 70842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return T.getCloseLocation(); 70942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 71042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 71176f3f69db1416425070177243e9f390122c553e0Richard Smith Result = Actions.ActOnDecltypeExpression(Result.take()); 71276f3f69db1416425070177243e9f390122c553e0Richard Smith if (Result.isInvalid()) { 71376f3f69db1416425070177243e9f390122c553e0Richard Smith DS.SetTypeSpecError(); 71476f3f69db1416425070177243e9f390122c553e0Richard Smith return T.getCloseLocation(); 71576f3f69db1416425070177243e9f390122c553e0Richard Smith } 71676f3f69db1416425070177243e9f390122c553e0Richard Smith 71742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie EndLoc = T.getCloseLocation(); 71842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 7196fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson 7206fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson const char *PrevSpec = 0; 721fec54013fcd0eb72642741584ca04c1bc292bef8John McCall unsigned DiagID; 7226fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson // Check for duplicate type specifiers (e.g. "int decltype(a)"). 7231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec, 72442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DiagID, Result.release())) { 725fec54013fcd0eb72642741584ca04c1bc292bef8John McCall Diag(StartLoc, DiagID) << PrevSpec; 72642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 72742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 72842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return EndLoc; 72942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie} 73042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 73142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikievoid Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec& DS, 73242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation StartLoc, 73342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation EndLoc) { 73442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // make sure we have a token we can turn into an annotation token 73542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (PP.isBacktrackEnabled()) 73642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie PP.RevertCachedTokens(1); 73742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie else 73842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie PP.EnterToken(Tok); 73942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 74042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Tok.setKind(tok::annot_decltype); 74142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie setExprAnnotation(Tok, DS.getTypeSpecType() == TST_decltype ? 74242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.getRepAsExpr() : ExprResult()); 74342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Tok.setAnnotationEndLoc(EndLoc); 74442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Tok.setLocation(StartLoc); 74542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie PP.AnnotateCachedTokens(Tok); 7466fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson} 7476fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson 748db5d44b775c60166074acd184ca9f1981c10c2a7Sean Huntvoid Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) { 749db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt assert(Tok.is(tok::kw___underlying_type) && 750db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt "Not an underlying type specifier"); 751db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 752db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt SourceLocation StartLoc = ConsumeToken(); 7534a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 7544a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen_after, 7554a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor "__underlying_type", tok::r_paren)) { 756db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt return; 757db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt } 758db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 759db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt TypeResult Result = ParseTypeName(); 760db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt if (Result.isInvalid()) { 761db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt SkipUntil(tok::r_paren); 762db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt return; 763db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt } 764db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 765db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt // Match the ')' 7664a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 7674a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.getCloseLocation().isInvalid()) 768db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt return; 769db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 770db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt const char *PrevSpec = 0; 771db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt unsigned DiagID; 772ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec, 773db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt DiagID, Result.release())) 774db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt Diag(StartLoc, DiagID) << PrevSpec; 775db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt} 776db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 77709048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// ParseBaseTypeSpecifier - Parse a C++ base-type-specifier which is either a 77809048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class name or decltype-specifier. Note that we only check that the result 77909048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// names a type; semantic analysis will need to verify that the type names a 78009048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class. The result is either a type or null, depending on whether a type 78109048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// name was found. 78242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// 78309048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// base-type-specifier: [C++ 10.1] 78409048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class-or-decltype 78509048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class-or-decltype: [C++ 10.1] 78609048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// nested-name-specifier[opt] class-name 78709048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// decltype-specifier 78842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// class-name: [C++ 9.1] 78942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// identifier 7907f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor/// simple-template-id 7911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 79222216eb4fb0936d2488fc03abd285d135c36ff01David BlaikieParser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc, 79322216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie SourceLocation &EndLocation) { 7947fe3878a36750515fb9772414ecb2489cf149d19David Blaikie // Ignore attempts to use typename 7957fe3878a36750515fb9772414ecb2489cf149d19David Blaikie if (Tok.is(tok::kw_typename)) { 7967fe3878a36750515fb9772414ecb2489cf149d19David Blaikie Diag(Tok, diag::err_expected_class_name_not_template) 7977fe3878a36750515fb9772414ecb2489cf149d19David Blaikie << FixItHint::CreateRemoval(Tok.getLocation()); 7987fe3878a36750515fb9772414ecb2489cf149d19David Blaikie ConsumeToken(); 7997fe3878a36750515fb9772414ecb2489cf149d19David Blaikie } 8007fe3878a36750515fb9772414ecb2489cf149d19David Blaikie 801152aa4b87633754801598ee282e1a17c3ec49257David Blaikie // Parse optional nested-name-specifier 802152aa4b87633754801598ee282e1a17c3ec49257David Blaikie CXXScopeSpec SS; 803152aa4b87633754801598ee282e1a17c3ec49257David Blaikie ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 804152aa4b87633754801598ee282e1a17c3ec49257David Blaikie 805152aa4b87633754801598ee282e1a17c3ec49257David Blaikie BaseLoc = Tok.getLocation(); 806152aa4b87633754801598ee282e1a17c3ec49257David Blaikie 80722216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie // Parse decltype-specifier 80842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // tok == kw_decltype is just error recovery, it can only happen when SS 80942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // isn't empty 81042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) { 811152aa4b87633754801598ee282e1a17c3ec49257David Blaikie if (SS.isNotEmpty()) 812152aa4b87633754801598ee282e1a17c3ec49257David Blaikie Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype) 813152aa4b87633754801598ee282e1a17c3ec49257David Blaikie << FixItHint::CreateRemoval(SS.getRange()); 81422216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie // Fake up a Declarator to use with ActOnTypeName. 81522216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie DeclSpec DS(AttrFactory); 81622216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie 817b57775709666e50cd925f9fc589d0fd895fc79a6David Blaikie EndLocation = ParseDecltypeSpecifier(DS); 81822216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie 81922216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 82022216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 82122216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie } 82222216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie 8237f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor // Check whether we have a template-id that names a type. 8247f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor if (Tok.is(tok::annot_template_id)) { 82525a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 826d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor if (TemplateId->Kind == TNK_Type_template || 827d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor TemplateId->Kind == TNK_Dependent_template_name) { 828059101f922de6eb765601459925f4c8914420b23Douglas Gregor AnnotateTemplateIdTokenAsType(); 8297f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 8307f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); 831b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType Type = getTypeAnnotation(Tok); 8327f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor EndLocation = Tok.getAnnotationEndLoc(); 8337f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor ConsumeToken(); 83431a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor 83531a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor if (Type) 83631a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return Type; 83731a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return true; 8387f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor } 8397f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 8407f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor // Fall through to produce an error below. 8417f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor } 8427f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 84342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor if (Tok.isNot(tok::identifier)) { 8441ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_class_name); 84531a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return true; 84642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor } 84742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 84884d0a19828599e8623223632d59447fd498999cfDouglas Gregor IdentifierInfo *Id = Tok.getIdentifierInfo(); 84984d0a19828599e8623223632d59447fd498999cfDouglas Gregor SourceLocation IdLoc = ConsumeToken(); 85084d0a19828599e8623223632d59447fd498999cfDouglas Gregor 85184d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (Tok.is(tok::less)) { 85284d0a19828599e8623223632d59447fd498999cfDouglas Gregor // It looks the user intended to write a template-id here, but the 85384d0a19828599e8623223632d59447fd498999cfDouglas Gregor // template-name was wrong. Try to fix that. 85484d0a19828599e8623223632d59447fd498999cfDouglas Gregor TemplateNameKind TNK = TNK_Type_template; 85584d0a19828599e8623223632d59447fd498999cfDouglas Gregor TemplateTy Template; 85623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(), 857059101f922de6eb765601459925f4c8914420b23Douglas Gregor &SS, Template, TNK)) { 85884d0a19828599e8623223632d59447fd498999cfDouglas Gregor Diag(IdLoc, diag::err_unknown_template_name) 85984d0a19828599e8623223632d59447fd498999cfDouglas Gregor << Id; 86084d0a19828599e8623223632d59447fd498999cfDouglas Gregor } 861193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 86284d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (!Template) 86384d0a19828599e8623223632d59447fd498999cfDouglas Gregor return true; 86484d0a19828599e8623223632d59447fd498999cfDouglas Gregor 865193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // Form the template name 86684d0a19828599e8623223632d59447fd498999cfDouglas Gregor UnqualifiedId TemplateName; 86784d0a19828599e8623223632d59447fd498999cfDouglas Gregor TemplateName.setIdentifier(Id, IdLoc); 868193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 86984d0a19828599e8623223632d59447fd498999cfDouglas Gregor // Parse the full template-id, then turn it into a type. 870e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), 871e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara TemplateName, true)) 87284d0a19828599e8623223632d59447fd498999cfDouglas Gregor return true; 87384d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (TNK == TNK_Dependent_template_name) 874059101f922de6eb765601459925f4c8914420b23Douglas Gregor AnnotateTemplateIdTokenAsType(); 875193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 87684d0a19828599e8623223632d59447fd498999cfDouglas Gregor // If we didn't end up with a typename token, there's nothing more we 87784d0a19828599e8623223632d59447fd498999cfDouglas Gregor // can do. 87884d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (Tok.isNot(tok::annot_typename)) 87984d0a19828599e8623223632d59447fd498999cfDouglas Gregor return true; 880193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 88184d0a19828599e8623223632d59447fd498999cfDouglas Gregor // Retrieve the type from the annotation token, consume that token, and 88284d0a19828599e8623223632d59447fd498999cfDouglas Gregor // return. 88384d0a19828599e8623223632d59447fd498999cfDouglas Gregor EndLocation = Tok.getAnnotationEndLoc(); 884b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType Type = getTypeAnnotation(Tok); 88584d0a19828599e8623223632d59447fd498999cfDouglas Gregor ConsumeToken(); 88684d0a19828599e8623223632d59447fd498999cfDouglas Gregor return Type; 88784d0a19828599e8623223632d59447fd498999cfDouglas Gregor } 88884d0a19828599e8623223632d59447fd498999cfDouglas Gregor 88942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // We have an identifier; check whether it is actually a type. 890c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain IdentifierInfo *CorrectedII = 0; 891059101f922de6eb765601459925f4c8914420b23Douglas Gregor ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true, 8929e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor false, ParsedType(), 893fad03b75e0297546c5d12ec420b5b79d5b7baa2aAbramo Bagnara /*IsCtorOrDtorName=*/false, 894c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain /*NonTrivialTypeSourceInfo=*/true, 895c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain &CorrectedII); 896193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam if (!Type) { 897124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor Diag(IdLoc, diag::err_expected_class_name); 89831a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return true; 89942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor } 90042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 90142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Consume the identifier. 90284d0a19828599e8623223632d59447fd498999cfDouglas Gregor EndLocation = IdLoc; 9035606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky 9045606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky // Fake up a Declarator to use with ActOnTypeName. 9050b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall DeclSpec DS(AttrFactory); 9065606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky DS.SetRangeStart(IdLoc); 9075606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky DS.SetRangeEnd(EndLocation); 908059101f922de6eb765601459925f4c8914420b23Douglas Gregor DS.getTypeSpecScope() = SS; 9095606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky 9105606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky const char *PrevSpec = 0; 9115606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky unsigned DiagID; 9125606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type); 9135606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky 9145606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 9155606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 91642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor} 91742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 918c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallvoid Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) { 919c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall while (Tok.is(tok::kw___single_inheritance) || 920c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall Tok.is(tok::kw___multiple_inheritance) || 921c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall Tok.is(tok::kw___virtual_inheritance)) { 922c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 923c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall SourceLocation AttrNameLoc = ConsumeToken(); 924c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 92593f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt SourceLocation(), 0, 0, AttributeList::AS_GNU); 926c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall } 927c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall} 928c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall 929c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// Determine whether the following tokens are valid after a type-specifier 930c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// which could be a standalone declaration. This will conservatively return 931c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// true if there's any doubt, and is appropriate for insert-';' fixits. 932139be7007eba3bd491ca50297888be507753a95dRichard Smithbool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) { 933c9f351700721150a985f21844fbfec55b04e861dRichard Smith // This switch enumerates the valid "follow" set for type-specifiers. 934c9f351700721150a985f21844fbfec55b04e861dRichard Smith switch (Tok.getKind()) { 935c9f351700721150a985f21844fbfec55b04e861dRichard Smith default: break; 936c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::semi: // struct foo {...} ; 937c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::star: // struct foo {...} * P; 938c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::amp: // struct foo {...} & R = ... 939c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::identifier: // struct foo {...} V ; 940c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::r_paren: //(struct foo {...} ) {4} 941c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::annot_cxxscope: // struct foo {...} a:: b; 942c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::annot_typename: // struct foo {...} a ::b; 943c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::annot_template_id: // struct foo {...} a<int> ::b; 944c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::l_paren: // struct foo {...} ( x); 945c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::comma: // __builtin_offsetof(struct foo{...} , 946c9f351700721150a985f21844fbfec55b04e861dRichard Smith return true; 947139be7007eba3bd491ca50297888be507753a95dRichard Smith case tok::colon: 948139be7007eba3bd491ca50297888be507753a95dRichard Smith return CouldBeBitfield; // enum E { ... } : 2; 949c9f351700721150a985f21844fbfec55b04e861dRichard Smith // Type qualifiers 950c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_const: // struct foo {...} const x; 951c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_volatile: // struct foo {...} volatile x; 952c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_restrict: // struct foo {...} restrict x; 953c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_inline: // struct foo {...} inline foo() {}; 954c9f351700721150a985f21844fbfec55b04e861dRichard Smith // Storage-class specifiers 955c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_static: // struct foo {...} static x; 956c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_extern: // struct foo {...} extern x; 957c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_typedef: // struct foo {...} typedef x; 958c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_register: // struct foo {...} register x; 959c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_auto: // struct foo {...} auto x; 960c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_mutable: // struct foo {...} mutable x; 961c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_constexpr: // struct foo {...} constexpr x; 962c9f351700721150a985f21844fbfec55b04e861dRichard Smith // As shown above, type qualifiers and storage class specifiers absolutely 963c9f351700721150a985f21844fbfec55b04e861dRichard Smith // can occur after class specifiers according to the grammar. However, 964c9f351700721150a985f21844fbfec55b04e861dRichard Smith // almost no one actually writes code like this. If we see one of these, 965c9f351700721150a985f21844fbfec55b04e861dRichard Smith // it is much more likely that someone missed a semi colon and the 966c9f351700721150a985f21844fbfec55b04e861dRichard Smith // type/storage class specifier we're seeing is part of the *next* 967c9f351700721150a985f21844fbfec55b04e861dRichard Smith // intended declaration, as in: 968c9f351700721150a985f21844fbfec55b04e861dRichard Smith // 969c9f351700721150a985f21844fbfec55b04e861dRichard Smith // struct foo { ... } 970c9f351700721150a985f21844fbfec55b04e861dRichard Smith // typedef int X; 971c9f351700721150a985f21844fbfec55b04e861dRichard Smith // 972c9f351700721150a985f21844fbfec55b04e861dRichard Smith // We'd really like to emit a missing semicolon error instead of emitting 973c9f351700721150a985f21844fbfec55b04e861dRichard Smith // an error on the 'int' saying that you can't have two type specifiers in 974c9f351700721150a985f21844fbfec55b04e861dRichard Smith // the same declaration of X. Because of this, we look ahead past this 975c9f351700721150a985f21844fbfec55b04e861dRichard Smith // token to see if it's a type specifier. If so, we know the code is 976c9f351700721150a985f21844fbfec55b04e861dRichard Smith // otherwise invalid, so we can produce the expected semi error. 977c9f351700721150a985f21844fbfec55b04e861dRichard Smith if (!isKnownToBeTypeSpecifier(NextToken())) 978c9f351700721150a985f21844fbfec55b04e861dRichard Smith return true; 979c9f351700721150a985f21844fbfec55b04e861dRichard Smith break; 980c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::r_brace: // struct bar { struct foo {...} } 981c9f351700721150a985f21844fbfec55b04e861dRichard Smith // Missing ';' at end of struct is accepted as an extension in C mode. 982c9f351700721150a985f21844fbfec55b04e861dRichard Smith if (!getLangOpts().CPlusPlus) 983c9f351700721150a985f21844fbfec55b04e861dRichard Smith return true; 984c9f351700721150a985f21844fbfec55b04e861dRichard Smith break; 985c9f351700721150a985f21844fbfec55b04e861dRichard Smith } 986c9f351700721150a985f21844fbfec55b04e861dRichard Smith return false; 987c9f351700721150a985f21844fbfec55b04e861dRichard Smith} 988c9f351700721150a985f21844fbfec55b04e861dRichard Smith 989e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or 990e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which 991e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that 99269730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith/// cannot start a definition. 993e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 994e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-specifier: [C++ class] 995e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head '{' member-specification[opt] '}' 996e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head '{' member-specification[opt] '}' attributes[opt] 997e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head: 998e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key identifier[opt] base-clause[opt] 999e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key nested-name-specifier identifier base-clause[opt] 1000e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key nested-name-specifier[opt] simple-template-id 1001e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-clause[opt] 1002e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] class-key attributes[opt] identifier[opt] base-clause[opt] 10031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU] class-key attributes[opt] nested-name-specifier 1004e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// identifier base-clause[opt] 10051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU] class-key attributes[opt] nested-name-specifier[opt] 1006e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// simple-template-id base-clause[opt] 1007e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key: 1008e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'class' 1009e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'struct' 1010e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'union' 1011e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1012e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier: [C++ dcl.type.elab] 10131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// class-key ::[opt] nested-name-specifier[opt] identifier 10141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// class-key ::[opt] nested-name-specifier[opt] 'template'[opt] 10151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// simple-template-id 1016e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1017e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// Note that the C++ class-specifier and elaborated-type-specifier, 1018e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// together, subsume the C99 struct-or-union-specifier: 1019e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1020e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union-specifier: [C99 6.7.2.1] 1021e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union identifier[opt] '{' struct-contents '}' 1022e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union identifier 1023e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] struct-or-union attributes[opt] identifier[opt] '{' struct-contents 1024e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// '}' attributes[opt] 1025e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] struct-or-union attributes[opt] identifier 1026e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union: 1027e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'struct' 1028e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'union' 10294c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattnervoid Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, 10304c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner SourceLocation StartLoc, DeclSpec &DS, 10314d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor const ParsedTemplateInfo &TemplateInfo, 1032efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor AccessSpecifier AS, 103369730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith bool EnteringContext, DeclSpecContext DSC) { 103417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos DeclSpec::TST TagType; 103517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos if (TagTokKind == tok::kw_struct) 103617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType = DeclSpec::TST_struct; 103717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos else if (TagTokKind == tok::kw___interface) 103817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType = DeclSpec::TST_interface; 103917d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos else if (TagTokKind == tok::kw_class) 104017d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType = DeclSpec::TST_class; 104117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos else { 10424c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner assert(TagTokKind == tok::kw_union && "Not a class specifier"); 10434c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner TagType = DeclSpec::TST_union; 10444c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner } 1045e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1046374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor if (Tok.is(tok::code_completion)) { 1047374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor // Code completion for a struct, class, or union name. 104823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteTag(getCurScope(), TagType); 10497d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return cutOffParsing(); 1050374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor } 1051193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 1052926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // C++03 [temp.explicit] 14.7.2/8: 1053926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // The usual access checking rules do not apply to names used to specify 1054926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // explicit instantiations. 1055926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // 1056926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // As an extension we do not perform access checking on the names used to 1057926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // specify explicit specializations either. This is important to allow 1058926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // specializing traits classes for private types. 105913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // 106013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // Note that we don't suppress if this turns out to be an elaborated 106113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // type specifier. 106213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall bool shouldDelayDiagsInTag = 106313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation || 106413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization); 106513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag); 1066926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth 10672edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ParsedAttributesWithRange attrs(AttrFactory); 1068e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If attributes exist after tag, parse them. 1069e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw___attribute)) 10707f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseGNUAttributes(attrs); 1071e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1072f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff // If declspecs exist after tag, parse them. 1073b1d397c23e1f8fd8b404d5731d531e7500f7140dJohn McCall while (Tok.is(tok::kw___declspec)) 10747f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseMicrosoftDeclSpec(attrs); 1075193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 1076c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall // Parse inheritance specifiers. 1077c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall if (Tok.is(tok::kw___single_inheritance) || 1078c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall Tok.is(tok::kw___multiple_inheritance) || 1079c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall Tok.is(tok::kw___virtual_inheritance)) 1080c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ParseMicrosoftInheritanceClassAttributes(attrs); 1081c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall 1082bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // If C++0x attributes exist here, parse them. 1083bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Are we consistent with the ordering of parsing of different 1084bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // styles of attributes? 10857f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseCXX0XAttributes(attrs); 10861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 108720c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley if (TagType == DeclSpec::TST_struct && 1088b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor !Tok.is(tok::identifier) && 1089b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.getIdentifierInfo() && 1090b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor (Tok.is(tok::kw___is_arithmetic) || 1091b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_convertible) || 109220c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley Tok.is(tok::kw___is_empty) || 1093b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_floating_point) || 1094b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_function) || 109520c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley Tok.is(tok::kw___is_fundamental) || 1096b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_integral) || 1097b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_member_function_pointer) || 1098b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_member_pointer) || 1099b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_pod) || 1100b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_pointer) || 1101b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_same) || 1102877222e2491bbc40a5c74cc100c540983f306b70Douglas Gregor Tok.is(tok::kw___is_scalar) || 1103b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_signed) || 1104b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_unsigned) || 1105b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_void))) { 1106688761409155b47c39eb5dae1b8c6c8a9f43307aDouglas Gregor // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the 1107b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // name of struct templates, but some are keywords in GCC >= 4.3 1108b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // and Clang. Therefore, when we see the token sequence "struct 1109b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // X", make X into a normal identifier rather than a keyword, to 1110b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // allow libstdc++ 4.2 and libc++ to work properly. 1111646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis Tok.getIdentifierInfo()->RevertTokenIDToIdentifier(); 1112b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor Tok.setKind(tok::identifier); 1113b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor } 11141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1115eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Parse the (optional) nested-name-specifier. 1116aa87d33309f505b68c3bfc17486c93e4d224b24fJohn McCall CXXScopeSpec &SS = DS.getTypeSpecScope(); 11174e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus) { 111808d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner // "FOO : BAR" is not a potential typo for "FOO::BAR". 111908d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner ColonProtectionRAIIObject X(*this); 1120193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 1121efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext)) 1122207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall DS.SetTypeSpecError(); 11239ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall if (SS.isSet()) 112408d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) 112508d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner Diag(Tok, diag::err_expected_ident); 112608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner } 1127cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor 11282cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams; 11292cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor 1130cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor // Parse the (optional) class name or simple-template-id. 1131e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IdentifierInfo *Name = 0; 1132e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation NameLoc; 113339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateIdAnnotation *TemplateId = 0; 1134e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::identifier)) { 1135e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Name = Tok.getIdentifierInfo(); 1136e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor NameLoc = ConsumeToken(); 1137193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 11384e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Tok.is(tok::less) && getLangOpts().CPlusPlus) { 1139193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // The name was supposed to refer to a template, but didn't. 11402cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // Eat the template argument list and try to continue parsing this as 11412cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // a class (or template thereof). 11422cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor TemplateArgList TemplateArgs; 11432cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor SourceLocation LAngleLoc, RAngleLoc; 1144059101f922de6eb765601459925f4c8914420b23Douglas Gregor if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, SS, 11452cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor true, LAngleLoc, 1146314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor TemplateArgs, RAngleLoc)) { 11472cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // We couldn't parse the template argument list at all, so don't 11482cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // try to give any location information for the list. 11492cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor LAngleLoc = RAngleLoc = SourceLocation(); 11502cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor } 1151193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 11522cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor Diag(NameLoc, diag::err_explicit_spec_non_template) 115317d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) 115417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos << (TagType == DeclSpec::TST_class? 0 115517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos : TagType == DeclSpec::TST_struct? 1 115617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos : TagType == DeclSpec::TST_interface? 2 115717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos : 3) 115817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos << Name 115917d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos << SourceRange(LAngleLoc, RAngleLoc); 116017d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos 1161193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // Strip off the last template parameter list if it was empty, since 1162c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor // we've removed its template argument list. 1163c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) { 1164c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor if (TemplateParams && TemplateParams->size() > 1) { 1165c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor TemplateParams->pop_back(); 1166c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor } else { 1167c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor TemplateParams = 0; 1168193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind 1169c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor = ParsedTemplateInfo::NonTemplate; 1170c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor } 1171c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor } else if (TemplateInfo.Kind 1172c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor == ParsedTemplateInfo::ExplicitInstantiation) { 1173c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor // Pretend this is just a forward declaration. 11742cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor TemplateParams = 0; 1175193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind 11762cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor = ParsedTemplateInfo::NonTemplate; 1177193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc 1178c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor = SourceLocation(); 1179c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc 1180c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor = SourceLocation(); 11812cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor } 11822cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor } 118339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor } else if (Tok.is(tok::annot_template_id)) { 118425a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateId = takeTemplateIdAnnotation(Tok); 118539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor NameLoc = ConsumeToken(); 1186cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor 1187059101f922de6eb765601459925f4c8914420b23Douglas Gregor if (TemplateId->Kind != TNK_Type_template && 1188059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->Kind != TNK_Dependent_template_name) { 118939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // The template-name in the simple-template-id refers to 119039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // something other than a class template. Give an appropriate 119139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // error message and skip to the ';'. 119239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor SourceRange Range(NameLoc); 119339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (SS.isNotEmpty()) 119439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor Range.setBegin(SS.getBeginLoc()); 119539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor 119639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template) 119739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor << Name << static_cast<int>(TemplateId->Kind) << Range; 11981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 119939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor DS.SetTypeSpecError(); 120039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor SkipUntil(tok::semi, false, true); 120139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor return; 1202cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor } 1203e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1204e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 12057796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // There are four options here. 12067796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - If we are in a trailing return type, this is always just a reference, 12077796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // and we must not try to parse a definition. For instance, 12087796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // [] () -> struct S { }; 12097796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // does not define a type. 12107796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - If we have 'struct foo {...', 'struct foo :...', 12117796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // 'struct foo final :' or 'struct foo final {', then this is a definition. 12127796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - If we have 'struct foo;', then this is either a forward declaration 12137796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // or a friend declaration, which have to be treated differently. 12147796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - Otherwise we have something like 'struct foo xyz', a reference. 121569730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // However, in type-specifier-seq's, things look like declarations but are 121669730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // just references, e.g. 121769730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // new struct s; 1218d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl // or 121969730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // &T::operator struct s; 122069730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // For these, DSC is DSC_type_specifier. 1221f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall Sema::TagUseKind TUK; 12227796eb5643244f3134834253ce5ea89107ac21c1Richard Smith if (DSC == DSC_trailing) 12237796eb5643244f3134834253ce5ea89107ac21c1Richard Smith TUK = Sema::TUK_Reference; 12247796eb5643244f3134834253ce5ea89107ac21c1Richard Smith else if (Tok.is(tok::l_brace) || 12257796eb5643244f3134834253ce5ea89107ac21c1Richard Smith (getLangOpts().CPlusPlus && Tok.is(tok::colon)) || 12267796eb5643244f3134834253ce5ea89107ac21c1Richard Smith (isCXX0XFinalKeyword() && 12276f42669b7c0b81b07a15a0483aa5e897ce57cb45David Blaikie (NextToken().is(tok::l_brace) || NextToken().is(tok::colon)))) { 1228d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor if (DS.isFriendSpecified()) { 1229d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // C++ [class.friend]p2: 1230d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // A class shall not be defined in a friend declaration. 1231bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith Diag(Tok.getLocation(), diag::err_friend_decl_defines_type) 1232d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor << SourceRange(DS.getFriendSpecLoc()); 1233d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor 1234d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // Skip everything up to the semicolon, so that this looks like a proper 1235d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // friend class (or template thereof) declaration. 1236d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor SkipUntil(tok::semi, true, true); 1237f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = Sema::TUK_Friend; 1238d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor } else { 1239d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // Okay, this is a class definition. 1240f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = Sema::TUK_Definition; 1241d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor } 1242c9f351700721150a985f21844fbfec55b04e861dRichard Smith } else if (DSC != DSC_type_specifier && 1243c9f351700721150a985f21844fbfec55b04e861dRichard Smith (Tok.is(tok::semi) || 1244139be7007eba3bd491ca50297888be507753a95dRichard Smith (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) { 1245f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration; 124617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos if (Tok.isNot(tok::semi)) { 124717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos // A semicolon was missing after this declaration. Diagnose and recover. 124817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, 124917d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos DeclSpec::getSpecifierName(TagType)); 125017d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos PP.EnterToken(Tok); 125117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos Tok.setKind(tok::semi); 125217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos } 1253c9f351700721150a985f21844fbfec55b04e861dRichard Smith } else 1254f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = Sema::TUK_Reference; 1255e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 125613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // If this is an elaborated type specifier, and we delayed 125713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // diagnostics before, just merge them into the current pool. 125813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall if (shouldDelayDiagsInTag) { 125913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall diagsFromTag.done(); 126013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall if (TUK == Sema::TUK_Reference) 126113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall diagsFromTag.redelay(); 126213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall } 126313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall 1264207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error || 1265f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK != Sema::TUK_Definition)) { 1266207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall if (DS.getTypeSpecType() != DeclSpec::TST_error) { 1267207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall // We have a declaration or reference to an anonymous class. 1268207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall Diag(StartLoc, diag::err_anon_type_definition) 1269207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall << DeclSpec::getSpecifierName(TagType); 1270207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall } 1271e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1272e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SkipUntil(tok::comma, true); 1273e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor return; 1274e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1275e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1276ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor // Create the tag portion of the class or class template. 1277d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall DeclResult TagOrTempResult = true; // invalid 1278d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall TypeResult TypeResult = true; // invalid 12794d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 1280402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor bool Owned = false; 1281f1bbbb49f06a7462476cd88166fccda5feb15cabJohn McCall if (TemplateId) { 12824d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // Explicit specialization, class template partial specialization, 12834d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // or explicit instantiation. 12845354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), 128539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->NumArgs); 12864d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && 1287f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK == Sema::TUK_Declaration) { 12884d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // This is an explicit instantiation of a class template. 12892edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 12902edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 12914d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TagOrTempResult 129223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnExplicitInstantiation(getCurScope(), 129345f965581935791a018df829a14dff53c1dd8f47Douglas Gregor TemplateInfo.ExternLoc, 12941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateInfo.TemplateLoc, 12954d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TagType, 12961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump StartLoc, 12974d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor SS, 12982b5289b6fd7e3d9899868410a498c081c9595662John McCall TemplateId->Template, 12991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->TemplateNameLoc, 13001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->LAngleLoc, 13014d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TemplateArgsPtr, 13021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->RAngleLoc, 13037f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall attrs.getList()); 130474256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall 130574256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // Friend template-ids are treated as references unless 130674256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // they have template headers, in which case they're ill-formed 130774256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // (FIXME: "template <class T> friend class A<T>::B<int>;"). 130874256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // We diagnose this error in ActOnClassTemplateSpecialization. 1309f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall } else if (TUK == Sema::TUK_Reference || 1310f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall (TUK == Sema::TUK_Friend && 131174256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) { 13122edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 131355d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara TypeResult = Actions.ActOnTagTemplateIdType(TUK, TagType, StartLoc, 1314059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->SS, 131555d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara TemplateId->TemplateKWLoc, 1316059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->Template, 1317059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->TemplateNameLoc, 1318059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->LAngleLoc, 1319059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateArgsPtr, 132055d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara TemplateId->RAngleLoc); 13214d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor } else { 13224d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // This is an explicit specialization or a class template 13234d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // partial specialization. 13244d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TemplateParameterLists FakedParamLists; 13254d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 13264d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { 13274d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // This looks like an explicit instantiation, because we have 13284d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // something like 13294d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // 13304d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // template class Foo<X> 13314d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // 13323f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // but it actually has a definition. Most likely, this was 13334d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // meant to be an explicit specialization, but the user forgot 13344d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // the '<>' after 'template'. 1335f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall assert(TUK == Sema::TUK_Definition && "Expected a definition here"); 13364d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 13371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump SourceLocation LAngleLoc 13384d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc); 13391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(TemplateId->TemplateNameLoc, 13404d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor diag::err_explicit_instantiation_with_definition) 13414d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor << SourceRange(TemplateInfo.TemplateLoc) 1342849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor << FixItHint::CreateInsertion(LAngleLoc, "<>"); 13434d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 13444d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // Create a fake template parameter list that contains only 13454d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // "template<>", so that we treat this construct as a class 13464d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // template specialization. 13474d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor FakedParamLists.push_back( 13481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Actions.ActOnTemplateParameterList(0, SourceLocation(), 13494d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TemplateInfo.TemplateLoc, 13501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump LAngleLoc, 13511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 0, 0, 13524d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor LAngleLoc)); 13534d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TemplateParams = &FakedParamLists; 13544d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor } 13554d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 13564d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // Build the class template specialization. 13574d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TagOrTempResult 135823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK, 1359d023aec8907831a18d3514a95b843a7ee06b6b5eDouglas Gregor StartLoc, DS.getModulePrivateSpecLoc(), SS, 13602b5289b6fd7e3d9899868410a498c081c9595662John McCall TemplateId->Template, 13611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->TemplateNameLoc, 13621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->LAngleLoc, 136339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateArgsPtr, 13641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->RAngleLoc, 13657f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall attrs.getList(), 13665354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer MultiTemplateParamsArg( 1367cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor TemplateParams? &(*TemplateParams)[0] : 0, 1368cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor TemplateParams? TemplateParams->size() : 0)); 13694d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor } 13703f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && 1371f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK == Sema::TUK_Declaration) { 13723f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // Explicit instantiation of a member of a class template 13733f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // specialization, e.g., 13743f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // 13753f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // template struct Outer<int>::Inner; 13763f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // 13772edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 13782edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 13793f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor TagOrTempResult 138023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnExplicitInstantiation(getCurScope(), 138145f965581935791a018df829a14dff53c1dd8f47Douglas Gregor TemplateInfo.ExternLoc, 13821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateInfo.TemplateLoc, 13831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TagType, StartLoc, SS, Name, 13847f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall NameLoc, attrs.getList()); 13859a34edb710917798aa30263374f624f13b594605John McCall } else if (TUK == Sema::TUK_Friend && 13869a34edb710917798aa30263374f624f13b594605John McCall TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) { 13872edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 13882edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 13899a34edb710917798aa30263374f624f13b594605John McCall TagOrTempResult = 13909a34edb710917798aa30263374f624f13b594605John McCall Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(), 13919a34edb710917798aa30263374f624f13b594605John McCall TagType, StartLoc, SS, 13927f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall Name, NameLoc, attrs.getList(), 13935354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer MultiTemplateParamsArg( 13949a34edb710917798aa30263374f624f13b594605John McCall TemplateParams? &(*TemplateParams)[0] : 0, 13959a34edb710917798aa30263374f624f13b594605John McCall TemplateParams? TemplateParams->size() : 0)); 13963f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor } else { 13973f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && 1398f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK == Sema::TUK_Definition) { 13993f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // FIXME: Diagnose this particular error. 14003f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor } 14013f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor 14022edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition) 14032edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 14042edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 1405c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall bool IsDependent = false; 1406c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall 1407a25c4080a490ea2bab6f54094dd75b19eae83770John McCall // Don't pass down template parameter lists if this is just a tag 1408a25c4080a490ea2bab6f54094dd75b19eae83770John McCall // reference. For example, we don't need the template parameters here: 1409a25c4080a490ea2bab6f54094dd75b19eae83770John McCall // template <class T> class A *makeA(T t); 1410a25c4080a490ea2bab6f54094dd75b19eae83770John McCall MultiTemplateParamsArg TParams; 1411a25c4080a490ea2bab6f54094dd75b19eae83770John McCall if (TUK != Sema::TUK_Reference && TemplateParams) 1412a25c4080a490ea2bab6f54094dd75b19eae83770John McCall TParams = 1413a25c4080a490ea2bab6f54094dd75b19eae83770John McCall MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size()); 1414a25c4080a490ea2bab6f54094dd75b19eae83770John McCall 14153f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // Declaration or definition of a class type 14169a34edb710917798aa30263374f624f13b594605John McCall TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc, 14177f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall SS, Name, NameLoc, attrs.getList(), AS, 1418e761230ae3751b525cadd8066c74ec278ee4ef57Douglas Gregor DS.getModulePrivateSpecLoc(), 1419bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith TParams, Owned, IsDependent, 1420bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith SourceLocation(), false, 1421bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith clang::TypeResult()); 1422c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall 1423c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall // If ActOnTag said the type was dependent, try again with the 1424c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall // less common call. 14259a34edb710917798aa30263374f624f13b594605John McCall if (IsDependent) { 14269a34edb710917798aa30263374f624f13b594605John McCall assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend); 142723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK, 1428193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam SS, Name, StartLoc, NameLoc); 14299a34edb710917798aa30263374f624f13b594605John McCall } 14303f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor } 1431e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1432e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If there is a body, parse it and inform the actions module. 1433f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall if (TUK == Sema::TUK_Definition) { 1434bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall assert(Tok.is(tok::l_brace) || 14354e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie (getLangOpts().CPlusPlus && Tok.is(tok::colon)) || 14368a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson isCXX0XFinalKeyword()); 14374e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus) 1438212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get()); 143907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis else 1440212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get()); 1441e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1442e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1443b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall const char *PrevSpec = 0; 1444b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall unsigned DiagID; 1445b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall bool Result; 1446c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall if (!TypeResult.isInvalid()) { 14470daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, 14480daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara NameLoc.isValid() ? NameLoc : StartLoc, 1449b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall PrevSpec, DiagID, TypeResult.get()); 1450c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall } else if (!TagOrTempResult.isInvalid()) { 14510daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara Result = DS.SetTypeSpecType(TagType, StartLoc, 14520daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara NameLoc.isValid() ? NameLoc : StartLoc, 14530daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara PrevSpec, DiagID, TagOrTempResult.get(), Owned); 1454c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall } else { 1455ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor DS.SetTypeSpecError(); 145666e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson return; 145766e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson } 14581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1459b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall if (Result) 1460fec54013fcd0eb72642741584ca04c1bc292bef8John McCall Diag(StartLoc, DiagID) << PrevSpec; 1461193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 14624ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // At this point, we've successfully parsed a class-specifier in 'definition' 14634ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // form (e.g. "struct foo { int x; }". While we could just return here, we're 14644ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // going to look at what comes after it to improve error recovery. If an 14654ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // impossible token occurs next, we assume that the programmer forgot a ; at 14664ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // the end of the declaration and recover that way. 14674ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // 1468c9f351700721150a985f21844fbfec55b04e861dRichard Smith // Also enforce C++ [temp]p3: 1469c9f351700721150a985f21844fbfec55b04e861dRichard Smith // In a template-declaration which defines a class, no declarator 1470c9f351700721150a985f21844fbfec55b04e861dRichard Smith // is permitted. 147117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos if (TUK == Sema::TUK_Definition && 147217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) { 147317d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, 147417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos DeclSpec::getSpecifierName(TagType)); 147517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos // Push this token back into the preprocessor and change our current token 147617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos // to ';' so that the rest of the code recovers as though there were an 147717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos // ';' after the definition. 1478c9f351700721150a985f21844fbfec55b04e861dRichard Smith PP.EnterToken(Tok); 1479c9f351700721150a985f21844fbfec55b04e861dRichard Smith Tok.setKind(tok::semi); 14804ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner } 1481e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 1482e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 14831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived]. 1484e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1485e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-clause : [C++ class.derived] 1486e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ':' base-specifier-list 1487e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier-list: 1488e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier '...'[opt] 1489e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier-list ',' base-specifier '...'[opt] 1490d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseBaseClause(Decl *ClassDecl) { 1491e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor assert(Tok.is(tok::colon) && "Not a base clause"); 1492e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 1493e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1494f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Build up an array of parsed base specifiers. 14955f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CXXBaseSpecifier *, 8> BaseInfo; 1496f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor 1497e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor while (true) { 1498e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse a base-specifier. 1499f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor BaseResult Result = ParseBaseSpecifier(ClassDecl); 15005ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor if (Result.isInvalid()) { 1501e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Skip the rest of this base specifier, up until the comma or 1502e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // opening brace. 1503f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor SkipUntil(tok::comma, tok::l_brace, true, true); 1504f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor } else { 1505f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Add this to our array of base specifiers. 15065ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor BaseInfo.push_back(Result.get()); 1507e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1508e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1509e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If the next token is a comma, consume it and keep reading 1510e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // base-specifiers. 1511e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.isNot(tok::comma)) break; 15121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1513e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Consume the comma. 1514e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 1515e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1516f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor 1517f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Attach the base specifiers 1518beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size()); 1519e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 1520e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1521e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is 1522e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example: 1523e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class foo : public bar, virtual private baz { 1524e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers. 1525e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1526e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier: [C++ class.derived] 1527e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ::[opt] nested-name-specifier[opt] class-name 1528e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'virtual' access-specifier[opt] ::[opt] nested-name-specifier[opt] 152909048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// base-type-specifier 1530e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt] 153109048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// base-type-specifier 1532d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) { 1533e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor bool IsVirtual = false; 1534e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation StartLoc = Tok.getLocation(); 1535e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1536e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the 'virtual' keyword. 1537e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw_virtual)) { 1538e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 1539e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IsVirtual = true; 1540e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1541e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1542e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse an (optional) access specifier. 1543e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor AccessSpecifier Access = getAccessSpecifierIfPresent(); 154492f883177b162928a8e632e4e3b93fafd2b26072John McCall if (Access != AS_none) 1545e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 15461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1547e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the 'virtual' keyword (again!), in case it came after the 1548e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // access specifier. 1549e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw_virtual)) { 1550e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation VirtualLoc = ConsumeToken(); 1551e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (IsVirtual) { 1552e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Complain about duplicate 'virtual' 15531ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(VirtualLoc, diag::err_dup_virtual) 1554849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor << FixItHint::CreateRemoval(VirtualLoc); 1555e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1556e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1557e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IsVirtual = true; 1558e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1559e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 156042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Parse the class-name. 15617f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor SourceLocation EndLocation; 156222216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie SourceLocation BaseLoc; 156322216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation); 156431a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor if (BaseType.isInvalid()) 156542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return true; 15661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1567f90b27ad077c3339b62befc892382845339f9490Douglas Gregor // Parse the optional ellipsis (for a pack expansion). The ellipsis is 1568f90b27ad077c3339b62befc892382845339f9490Douglas Gregor // actually part of the base-specifier-list grammar productions, but we 1569f90b27ad077c3339b62befc892382845339f9490Douglas Gregor // parse it here for convenience. 1570f90b27ad077c3339b62befc892382845339f9490Douglas Gregor SourceLocation EllipsisLoc; 1571f90b27ad077c3339b62befc892382845339f9490Douglas Gregor if (Tok.is(tok::ellipsis)) 1572f90b27ad077c3339b62befc892382845339f9490Douglas Gregor EllipsisLoc = ConsumeToken(); 1573f90b27ad077c3339b62befc892382845339f9490Douglas Gregor 15741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Find the complete source range for the base-specifier. 15757f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor SourceRange Range(StartLoc, EndLocation); 15761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1577e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Notify semantic analysis that we have parsed a complete 1578e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // base-specifier. 1579a55e52c0802cae3b7c366a05c461d3d15074c1a3Sebastian Redl return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access, 1580f90b27ad077c3339b62befc892382845339f9490Douglas Gregor BaseType.get(), BaseLoc, EllipsisLoc); 1581e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 1582e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1583e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is 1584e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier. 1585e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1586e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// access-specifier: [C++ class.derived] 1587e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'private' 1588e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'protected' 1589e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public' 15901eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAccessSpecifier Parser::getAccessSpecifierIfPresent() const { 1591e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor switch (Tok.getKind()) { 1592e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor default: return AS_none; 1593e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_private: return AS_private; 1594e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_protected: return AS_protected; 1595e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_public: return AS_public; 1596e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1597e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 15984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 159974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor/// \brief If the given declarator has any parts for which parsing has to be 1600a058fd4f0a944174295f77169b438510dad389f8Richard Smith/// delayed, e.g., default arguments, create a late-parsed method declaration 1601a058fd4f0a944174295f77169b438510dad389f8Richard Smith/// record to handle the parsing at the end of the class definition. 160274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregorvoid Parser::HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo, 160374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor Decl *ThisDecl) { 1604d33133cdc1af466f9c276249b2621be03867888bEli Friedman // We just declared a member function. If this member function 1605a058fd4f0a944174295f77169b438510dad389f8Richard Smith // has any default arguments, we'll need to parse them later. 1606d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateParsedMethodDeclaration *LateMethod = 0; 16071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump DeclaratorChunk::FunctionTypeInfo &FTI 1608075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara = DeclaratorInfo.getFunctionTypeInfo(); 160974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 1610d33133cdc1af466f9c276249b2621be03867888bEli Friedman for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) { 1611d33133cdc1af466f9c276249b2621be03867888bEli Friedman if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) { 1612d33133cdc1af466f9c276249b2621be03867888bEli Friedman if (!LateMethod) { 1613d33133cdc1af466f9c276249b2621be03867888bEli Friedman // Push this method onto the stack of late-parsed method 1614d33133cdc1af466f9c276249b2621be03867888bEli Friedman // declarations. 1615d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor LateMethod = new LateParsedMethodDeclaration(this, ThisDecl); 1616d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor getCurrentClass().LateParsedDeclarations.push_back(LateMethod); 161723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor LateMethod->TemplateScope = getCurScope()->isTemplateParamScope(); 1618d33133cdc1af466f9c276249b2621be03867888bEli Friedman 1619d33133cdc1af466f9c276249b2621be03867888bEli Friedman // Add all of the parameters prior to this one (they don't 1620d33133cdc1af466f9c276249b2621be03867888bEli Friedman // have default arguments). 1621d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateMethod->DefaultArgs.reserve(FTI.NumArgs); 1622d33133cdc1af466f9c276249b2621be03867888bEli Friedman for (unsigned I = 0; I < ParamIdx; ++I) 1623d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateMethod->DefaultArgs.push_back( 16248f8210c47797f013e0fb24a26f9c4751b10783feDouglas Gregor LateParsedDefaultArgument(FTI.ArgInfo[I].Param)); 1625d33133cdc1af466f9c276249b2621be03867888bEli Friedman } 1626d33133cdc1af466f9c276249b2621be03867888bEli Friedman 162774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Add this parameter to the list of parameters (it may or may 1628d33133cdc1af466f9c276249b2621be03867888bEli Friedman // not have a default argument). 1629d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateMethod->DefaultArgs.push_back( 1630d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param, 1631d33133cdc1af466f9c276249b2621be03867888bEli Friedman FTI.ArgInfo[ParamIdx].DefaultArgTokens)); 1632d33133cdc1af466f9c276249b2621be03867888bEli Friedman } 1633d33133cdc1af466f9c276249b2621be03867888bEli Friedman } 1634d33133cdc1af466f9c276249b2621be03867888bEli Friedman} 1635d33133cdc1af466f9c276249b2621be03867888bEli Friedman 16361c94c16317c1a35c1549e022958188eea2567089Richard Smith/// isCXX0XVirtSpecifier - Determine whether the given token is a C++0x 16371f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier. 16381f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 16391f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier: 16401f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// override 16411f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// final 16421c94c16317c1a35c1549e022958188eea2567089Richard SmithVirtSpecifiers::Specifier Parser::isCXX0XVirtSpecifier(const Token &Tok) const { 16434e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().CPlusPlus) 1644cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson return VirtSpecifiers::VS_None; 1645cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 1646b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (Tok.is(tok::identifier)) { 1647b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson IdentifierInfo *II = Tok.getIdentifierInfo(); 16481f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 16497eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson // Initialize the contextual keywords. 16507eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson if (!Ident_final) { 16517eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson Ident_final = &PP.getIdentifierTable().get("final"); 16527eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson Ident_override = &PP.getIdentifierTable().get("override"); 16537eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson } 16547eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson 1655b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (II == Ident_override) 1656b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return VirtSpecifiers::VS_Override; 16571f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 1658b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (II == Ident_final) 1659b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return VirtSpecifiers::VS_Final; 1660b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson } 1661b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson 1662b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return VirtSpecifiers::VS_None; 16631f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson} 16641f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 16651f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// ParseOptionalCXX0XVirtSpecifierSeq - Parse a virt-specifier-seq. 16661f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 16671f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq: 16681f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier 16691f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq virt-specifier 1670b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlssonvoid Parser::ParseOptionalCXX0XVirtSpecifierSeq(VirtSpecifiers &VS) { 1671b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson while (true) { 1672cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson VirtSpecifiers::Specifier Specifier = isCXX0XVirtSpecifier(); 1673b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (Specifier == VirtSpecifiers::VS_None) 1674b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return; 1675b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson 1676b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson // C++ [class.mem]p8: 1677b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson // A virt-specifier-seq shall contain at most one of each virt-specifier. 1678cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson const char *PrevSpec = 0; 167946127a96b6dd6b93aa18d5f7a55bc2db8b52a2c9Anders Carlsson if (VS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec)) 1680b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier) 1681b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson << PrevSpec 1682b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson << FixItHint::CreateRemoval(Tok.getLocation()); 1683b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson 16844e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Diag(Tok.getLocation(), getLangOpts().CPlusPlus0x ? 16857fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_override_control_keyword : 16867fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::ext_override_control_keyword) 16877fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith << VirtSpecifiers::getSpecifierName(Specifier); 1688b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson ConsumeToken(); 1689b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson } 16901f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson} 16911f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 16928a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson/// isCXX0XFinalKeyword - Determine whether the next token is a C++0x 16938a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson/// contextual 'final' keyword. 16948a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlssonbool Parser::isCXX0XFinalKeyword() const { 16954e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().CPlusPlus) 16968a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson return false; 1697cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 16988a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson if (!Tok.is(tok::identifier)) 16998a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson return false; 1700cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 17018a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson // Initialize the contextual keywords. 17028a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson if (!Ident_final) { 17038a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson Ident_final = &PP.getIdentifierTable().get("final"); 17048a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson Ident_override = &PP.getIdentifierTable().get("override"); 1705cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson } 17068a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson 17078a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson return Tok.getIdentifierInfo() == Ident_final; 1708cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson} 1709cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 17104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration. 17114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 17124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declaration: 17134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// decl-specifier-seq[opt] member-declarator-list[opt] ';' 17144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// function-definition ';'[opt] 17154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO] 17164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// using-declaration [TODO] 1717511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration 17185aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson/// template-declaration 1719bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU] '__extension__' member-declaration 17204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 17214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator-list: 17224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator 17234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator-list ',' member-declarator 17244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 17254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator: 17261f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// declarator virt-specifier-seq[opt] pure-specifier[opt] 17274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// declarator constant-initializer[opt] 17287a614d8380297fcd2bc23986241905d97222948cRichard Smith/// [C++11] declarator brace-or-equal-initializer[opt] 17294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// identifier[opt] ':' constant-expression 17304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 17311f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq: 17321f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier 17331f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq virt-specifier 17341f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 17351f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier: 17361f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// override 17371f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// final 17381f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 1739e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl/// pure-specifier: 17404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// '= 0' 17414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 17424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// constant-initializer: 17434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// '=' constant-expression 17444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 174537b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregorvoid Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, 17465f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen AttributeList *AccessAttrs, 1747c9068d7dd94d439cec66c421115d15303e481025John McCall const ParsedTemplateInfo &TemplateInfo, 1748c9068d7dd94d439cec66c421115d15303e481025John McCall ParsingDeclRAIIObject *TemplateDiags) { 17498a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor if (Tok.is(tok::at)) { 17504e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjC1 && NextToken().isObjCAtKeyword(tok::objc_defs)) 17518a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor Diag(Tok, diag::err_at_defs_cxx); 17528a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor else 17538a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor Diag(Tok, diag::err_at_in_class); 17548a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor 17558a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor ConsumeToken(); 17568a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor SkipUntil(tok::r_brace); 17578a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor return; 17588a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor } 17598a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor 176060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // Access declarations. 176183a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith bool MalformedTypeSpec = false; 176260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall if (!TemplateInfo.Kind && 176383a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith (Tok.is(tok::identifier) || Tok.is(tok::coloncolon))) { 176483a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith if (TryAnnotateCXXScopeToken()) 176583a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith MalformedTypeSpec = true; 176683a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith 176783a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith bool isAccessDecl; 176883a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith if (Tok.isNot(tok::annot_cxxscope)) 176983a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith isAccessDecl = false; 177083a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith else if (NextToken().is(tok::identifier)) 177160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall isAccessDecl = GetLookAheadToken(2).is(tok::semi); 177260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall else 177360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall isAccessDecl = NextToken().is(tok::kw_operator); 177460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 177560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall if (isAccessDecl) { 177660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // Collect the scope specifier token we annotated earlier. 177760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall CXXScopeSpec SS; 1778efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 1779efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor /*EnteringContext=*/false); 178060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 178160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // Try to parse an unqualified-id. 1782e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara SourceLocation TemplateKWLoc; 178360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall UnqualifiedId Name; 1784e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), 1785e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara TemplateKWLoc, Name)) { 178660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall SkipUntil(tok::semi); 178760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall return; 178860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall } 178960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 179060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // TODO: recover from mistakenly-qualified operator declarations. 179160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall if (ExpectAndConsume(tok::semi, 179260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall diag::err_expected_semi_after, 179360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall "access declaration", 179460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall tok::semi)) 179560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall return; 179660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 179723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnUsingDeclaration(getCurScope(), AS, 179860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall false, SourceLocation(), 179960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall SS, Name, 180060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall /* AttrList */ 0, 180160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall /* IsTypeName */ false, 180260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall SourceLocation()); 180360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall return; 180460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall } 180560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall } 180660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 1807511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson // static_assert-declaration 1808c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne if (Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) { 180937b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor // FIXME: Check for templates 181097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner SourceLocation DeclEnd; 181197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner ParseStaticAssertDeclaration(DeclEnd); 1812682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 1813682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner } 18141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1815682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner if (Tok.is(tok::kw_template)) { 18161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump assert(!TemplateInfo.TemplateParams && 181737b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor "Nested template improperly parsed?"); 181897144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner SourceLocation DeclEnd; 18191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd, 18205f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen AS, AccessAttrs); 1821682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 1822682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner } 18235aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson 1824bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner // Handle: member-declaration ::= '__extension__' member-declaration 1825bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner if (Tok.is(tok::kw___extension__)) { 1826bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner // __extension__ silences extension warnings in the subexpression. 1827bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner ExtensionRAIIObject O(Diags); // Use RAII to do this. 1828bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner ConsumeToken(); 18295f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen return ParseCXXClassMemberDeclaration(AS, AccessAttrs, 18305f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen TemplateInfo, TemplateDiags); 1831bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner } 18329cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 18334ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it 18344ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // is a bitfield. 1835a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner ColonProtectionRAIIObject X(*this); 1836193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 18370b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributesWithRange attrs(AttrFactory); 1838bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // Optional C++0x attribute-specifier 18397f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseCXX0XAttributes(attrs); 18407f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseMicrosoftAttributes(attrs); 1841bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 18429cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (Tok.is(tok::kw_using)) { 18437f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ProhibitAttributes(attrs); 18441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18459cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Eat 'using'. 18469cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SourceLocation UsingLoc = ConsumeToken(); 18479cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 18489cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (Tok.is(tok::kw_namespace)) { 18499cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor Diag(UsingLoc, diag::err_using_namespace_in_class); 18509cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SkipUntil(tok::semi, true, true); 1851ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner } else { 18529cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SourceLocation DeclEnd; 18533e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // Otherwise, it must be a using-declaration or an alias-declaration. 185478b810559d89e996e00684335407443936ce34a1John McCall ParseUsingDeclaration(Declarator::MemberContext, TemplateInfo, 185578b810559d89e996e00684335407443936ce34a1John McCall UsingLoc, DeclEnd, AS); 18569cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 18579cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor return; 18589cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 18599cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 18602287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins // Hold late-parsed attributes so we can attach a Decl to them later. 18612287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins LateParsedAttrList CommonLateParsedAttrs; 18622287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins 18634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // decl-specifier-seq: 18644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the common declaration-specifiers piece. 1865c9068d7dd94d439cec66c421115d15303e481025John McCall ParsingDeclSpec DS(*this, TemplateDiags); 18667f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall DS.takeAttributesFrom(attrs); 186783a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith if (MalformedTypeSpec) 186883a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith DS.SetTypeSpecError(); 18692287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class, 18702287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins &CommonLateParsedAttrs); 18714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 18725354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer MultiTemplateParamsArg TemplateParams( 1873dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0, 1874dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0); 1875dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall 18764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) { 18774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 1878d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl *TheDecl = 18790f4be74ff0273e505d383f89174ef539828424edChandler Carruth Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS, TemplateParams); 1880c9068d7dd94d439cec66c421115d15303e481025John McCall DS.complete(TheDecl); 188167d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall return; 18824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 188307952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis 188454abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext); 18854867347e82648d3baf09524b98b09c297a5a198fNico Weber VirtSpecifiers VS; 18864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 1887eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // Hold late-parsed attributes so we can attach a Decl to them later. 1888eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski LateParsedAttrList LateParsedAttrs; 1889eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski 1890a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor SourceLocation EqualLoc; 1891a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor bool HasInitializer = false; 1892a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor ExprResult Init; 18933a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.isNot(tok::colon)) { 1894a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 1895a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner ColonProtectionRAIIObject X(*this); 1896a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner 18973a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // Parse the first declarator. 18983a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 1899a058fd4f0a944174295f77169b438510dad389f8Richard Smith // Error parsing the declarator? 190010bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor if (!DeclaratorInfo.hasName()) { 19013a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // If so, skip until the semi-colon or a }. 1902d941fa4ff0d0d64b5a541dbd4f99693bff7f6e8dSebastian Redl SkipUntil(tok::r_brace, true, true); 19033a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.is(tok::semi)) 19043a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeToken(); 1905682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 19064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 19074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 19084867347e82648d3baf09524b98b09c297a5a198fNico Weber ParseOptionalCXX0XVirtSpecifierSeq(VS); 19094867347e82648d3baf09524b98b09c297a5a198fNico Weber 19101b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson // If attributes exist after the declarator, but before an '{', parse them. 1911eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); 19121b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson 19136a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet // MSVC permits pure specifier on inline functions declared at class scope. 19146a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet // Hence check for =0 before checking for function definition. 19154e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().MicrosoftExt && Tok.is(tok::equal) && 19166a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet DeclaratorInfo.isFunctionDeclarator() && 19176a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet NextToken().is(tok::numeric_constant)) { 1918a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor EqualLoc = ConsumeToken(); 19196a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet Init = ParseInitializer(); 19206a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet if (Init.isInvalid()) 19216a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet SkipUntil(tok::comma, true, true); 1922a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor else 1923a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor HasInitializer = true; 19246a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet } 19256a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet 192645fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor FunctionDefinitionKind DefinitionKind = FDK_Declaration; 19273a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // function-definition: 19287a614d8380297fcd2bc23986241905d97222948cRichard Smith // 19297a614d8380297fcd2bc23986241905d97222948cRichard Smith // In C++11, a non-function declarator followed by an open brace is a 19307a614d8380297fcd2bc23986241905d97222948cRichard Smith // braced-init-list for an in-class member initialization, not an 19317a614d8380297fcd2bc23986241905d97222948cRichard Smith // erroneous function definition. 19324e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Tok.is(tok::l_brace) && !getLangOpts().CPlusPlus0x) { 193345fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Definition; 1934e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } else if (DeclaratorInfo.isFunctionDeclarator()) { 19357a614d8380297fcd2bc23986241905d97222948cRichard Smith if (Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) { 193645fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Definition; 1937e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } else if (Tok.is(tok::equal)) { 1938e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt const Token &KW = NextToken(); 193945fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor if (KW.is(tok::kw_default)) 194045fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Defaulted; 194145fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor else if (KW.is(tok::kw_delete)) 194245fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Deleted; 1943e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } 1944e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } 1945e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt 194645fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor if (DefinitionKind) { 19473a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (!DeclaratorInfo.isFunctionDeclarator()) { 194865ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params); 19493a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeBrace(); 195065ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu SkipUntil(tok::r_brace, /*StopAtSemi*/false); 19519ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor 19529ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor // Consume the optional ';' 19539ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor if (Tok.is(tok::semi)) 19549ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor ConsumeToken(); 1955682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 19563a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 19573a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis 19583a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 195965ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu Diag(DeclaratorInfo.getIdentifierLoc(), 196065ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu diag::err_function_declared_typedef); 19613a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // This recovery skips the entire function body. It would be nice 19623a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // to simply call ParseCXXInlineMethodDef() below, however Sema 19633a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // assumes the declarator represents a function, not a typedef. 19643a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeBrace(); 196565ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu SkipUntil(tok::r_brace, /*StopAtSemi*/false); 19669ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor 19679ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor // Consume the optional ';' 19689ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor if (Tok.is(tok::semi)) 19699ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor ConsumeToken(); 1970682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 19713a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 19724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 1973eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski Decl *FunDecl = 19745f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo, TemplateInfo, 197545fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor VS, DefinitionKind, Init); 1976eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski 19772287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) { 19782287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins CommonLateParsedAttrs[i]->addDecl(FunDecl); 19792287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins } 1980eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) { 19812287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins LateParsedAttrs[i]->addDecl(FunDecl); 1982eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski } 1983eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski LateParsedAttrs.clear(); 1984e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt 1985e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt // Consume the ';' - it's optional unless we have a delete or default 19864b0e6f1da341510c1ad83eaf4c836f3134d0156aRichard Trieu if (Tok.is(tok::semi)) 1987eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith ConsumeExtraSemi(AfterMemberFunctionDefinition); 19889ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor 1989682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 19903a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 19914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 19924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 19934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator-list: 19944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator 19954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator-list ',' member-declarator 19964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 19975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Decl *, 8> DeclsInGroup; 199860d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult BitfieldSize; 19991c94c16317c1a35c1549e022958188eea2567089Richard Smith bool ExpectSemi = true; 20004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 20014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis while (1) { 20024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator: 20034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // declarator pure-specifier[opt] 20047a614d8380297fcd2bc23986241905d97222948cRichard Smith // declarator brace-or-equal-initializer[opt] 20054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // identifier[opt] ':' constant-expression 20064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::colon)) { 20074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 20080e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl BitfieldSize = ParseConstantExpression(); 20090e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (BitfieldSize.isInvalid()) 20104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::comma, true, true); 20114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 20121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2013e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner // If a simple-asm-expr is present, parse it. 2014e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner if (Tok.is(tok::kw_asm)) { 2015e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner SourceLocation Loc; 201660d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AsmLabel(ParseSimpleAsm(&Loc)); 2017e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner if (AsmLabel.isInvalid()) 2018e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner SkipUntil(tok::comma, true, true); 2019e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner 2020e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner DeclaratorInfo.setAsmLabel(AsmLabel.release()); 2021e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner DeclaratorInfo.SetRangeEnd(Loc); 2022e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner } 2023e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner 20244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If attributes exist after the declarator, parse them. 2025eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); 20264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 20277a614d8380297fcd2bc23986241905d97222948cRichard Smith // FIXME: When g++ adds support for this, we'll need to check whether it 20287a614d8380297fcd2bc23986241905d97222948cRichard Smith // goes before or after the GNU attributes and __asm__. 20297a614d8380297fcd2bc23986241905d97222948cRichard Smith ParseOptionalCXX0XVirtSpecifierSeq(VS); 20307a614d8380297fcd2bc23986241905d97222948cRichard Smith 2031ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith InClassInitStyle HasInClassInit = ICIS_NoInit; 2032a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor if ((Tok.is(tok::equal) || Tok.is(tok::l_brace)) && !HasInitializer) { 20337a614d8380297fcd2bc23986241905d97222948cRichard Smith if (BitfieldSize.get()) { 20347a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(Tok, diag::err_bitfield_member_init); 20357a614d8380297fcd2bc23986241905d97222948cRichard Smith SkipUntil(tok::comma, true, true); 20367a614d8380297fcd2bc23986241905d97222948cRichard Smith } else { 2037147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor HasInitializer = true; 2038ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith if (!DeclaratorInfo.isDeclarationOfFunction() && 2039ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith DeclaratorInfo.getDeclSpec().getStorageClassSpec() 2040ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith != DeclSpec::SCS_static && 2041ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith DeclaratorInfo.getDeclSpec().getStorageClassSpec() 2042ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith != DeclSpec::SCS_typedef) 2043ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith HasInClassInit = Tok.is(tok::equal) ? ICIS_CopyInit : ICIS_ListInit; 20447a614d8380297fcd2bc23986241905d97222948cRichard Smith } 20457a614d8380297fcd2bc23986241905d97222948cRichard Smith } 20467a614d8380297fcd2bc23986241905d97222948cRichard Smith 204707952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // NOTE: If Sema is the Action module and declarator is an instance field, 2048682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner // this call will *not* return the created decl; It will return null. 204907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // See Sema::ActOnCXXMemberDeclarator for details. 205067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall 2051d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl *ThisDecl = 0; 205267d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall if (DS.isFriendSpecified()) { 2053bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall // TODO: handle initializers, bitfields, 'delete' 205423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo, 20553fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer TemplateParams); 205637b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor } else { 205723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, 205867d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall DeclaratorInfo, 20593fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer TemplateParams, 206067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall BitfieldSize.release(), 2061ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith VS, HasInClassInit); 20625f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen if (AccessAttrs) 20635f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs, 20645f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen false, true); 206537b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor } 2066147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor 2067eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // Set the Decl for any late parsed attributes 20682287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) { 20692287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins CommonLateParsedAttrs[i]->addDecl(ThisDecl); 20702287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins } 2071eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) { 20722287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins LateParsedAttrs[i]->addDecl(ThisDecl); 2073eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski } 2074eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski LateParsedAttrs.clear(); 2075eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski 2076147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // Handle the initializer. 2077ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith if (HasInClassInit != ICIS_NoInit) { 2078147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // The initializer was deferred; parse it and cache the tokens. 20794e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Diag(Tok, getLangOpts().CPlusPlus0x ? 20807fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_nonstatic_member_init : 20817fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::ext_nonstatic_member_init); 20827fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 20837a614d8380297fcd2bc23986241905d97222948cRichard Smith if (DeclaratorInfo.isArrayOfUnknownBound()) { 2084ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith // C++11 [dcl.array]p3: An array bound may also be omitted when the 2085ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith // declarator is followed by an initializer. 20867a614d8380297fcd2bc23986241905d97222948cRichard Smith // 20877a614d8380297fcd2bc23986241905d97222948cRichard Smith // A brace-or-equal-initializer for a member-declarator is not an 20883164c14cadbb09a05ba811602221e9156077cf44David Blaikie // initializer in the grammar, so this is ill-formed. 20897a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(Tok, diag::err_incomplete_array_member_init); 20907a614d8380297fcd2bc23986241905d97222948cRichard Smith SkipUntil(tok::comma, true, true); 20913164c14cadbb09a05ba811602221e9156077cf44David Blaikie if (ThisDecl) 20923164c14cadbb09a05ba811602221e9156077cf44David Blaikie // Avoid later warnings about a class member of incomplete type. 20933164c14cadbb09a05ba811602221e9156077cf44David Blaikie ThisDecl->setInvalidDecl(); 20947a614d8380297fcd2bc23986241905d97222948cRichard Smith } else 20957a614d8380297fcd2bc23986241905d97222948cRichard Smith ParseCXXNonStaticMemberInitializer(ThisDecl); 2096147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor } else if (HasInitializer) { 2097147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // Normal initializer. 2098a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor if (!Init.isUsable()) 2099552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor Init = ParseCXXMemberInitializer(ThisDecl, 2100a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor DeclaratorInfo.isDeclarationOfFunction(), EqualLoc); 2101a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor 2102147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor if (Init.isInvalid()) 2103147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor SkipUntil(tok::comma, true, true); 2104147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor else if (ThisDecl) 210533deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid(), 2106a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor DS.getTypeSpecType() == DeclSpec::TST_auto); 2107147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static) { 2108147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // No initializer. 2109147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor Actions.ActOnUninitializedDecl(ThisDecl, 2110147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor DS.getTypeSpecType() == DeclSpec::TST_auto); 21117a614d8380297fcd2bc23986241905d97222948cRichard Smith } 2112147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor 2113147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor if (ThisDecl) { 2114147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor Actions.FinalizeDeclaration(ThisDecl); 2115147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor DeclsInGroup.push_back(ThisDecl); 2116147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor } 2117147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor 2118e531001b7e44bee5c4ec0be93efbc75adb37a0e3Richard Smith if (ThisDecl && DeclaratorInfo.isFunctionDeclarator() && 2119147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor DeclaratorInfo.getDeclSpec().getStorageClassSpec() 2120147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor != DeclSpec::SCS_typedef) { 212174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl); 2122147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor } 2123147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor 2124147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor DeclaratorInfo.complete(ThisDecl); 21257a614d8380297fcd2bc23986241905d97222948cRichard Smith 21264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If we don't have a comma, it is either the end of the list (a ';') 21274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // or an error, bail out. 21284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.isNot(tok::comma)) 21294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 21301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Consume the comma. 21321c94c16317c1a35c1549e022958188eea2567089Richard Smith SourceLocation CommaLoc = ConsumeToken(); 21331c94c16317c1a35c1549e022958188eea2567089Richard Smith 21341c94c16317c1a35c1549e022958188eea2567089Richard Smith if (Tok.isAtStartOfLine() && 21351c94c16317c1a35c1549e022958188eea2567089Richard Smith !MightBeDeclarator(Declarator::MemberContext)) { 21361c94c16317c1a35c1549e022958188eea2567089Richard Smith // This comma was followed by a line-break and something which can't be 21371c94c16317c1a35c1549e022958188eea2567089Richard Smith // the start of a declarator. The comma was probably a typo for a 21381c94c16317c1a35c1549e022958188eea2567089Richard Smith // semicolon. 21391c94c16317c1a35c1549e022958188eea2567089Richard Smith Diag(CommaLoc, diag::err_expected_semi_declaration) 21401c94c16317c1a35c1549e022958188eea2567089Richard Smith << FixItHint::CreateReplacement(CommaLoc, ";"); 21411c94c16317c1a35c1549e022958188eea2567089Richard Smith ExpectSemi = false; 21421c94c16317c1a35c1549e022958188eea2567089Richard Smith break; 21431c94c16317c1a35c1549e022958188eea2567089Richard Smith } 21441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the next declarator. 21464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclaratorInfo.clear(); 21474867347e82648d3baf09524b98b09c297a5a198fNico Weber VS.clear(); 2148147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor BitfieldSize = true; 2149a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor Init = true; 2150a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor HasInitializer = false; 21517984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith DeclaratorInfo.setCommaLoc(CommaLoc); 21521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 21534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Attributes are only allowed on the second declarator. 21547f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseGNUAttributes(DeclaratorInfo); 21554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 21563a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.isNot(tok::colon)) 21573a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 21584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 21594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 21601c94c16317c1a35c1549e022958188eea2567089Richard Smith if (ExpectSemi && 21611c94c16317c1a35c1549e022958188eea2567089Richard Smith ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) { 2162ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner // Skip to end of block or statement. 2163ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner SkipUntil(tok::r_brace, true, true); 2164ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner // If we stopped at a ';', eat it. 2165ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner if (Tok.is(tok::semi)) ConsumeToken(); 2166682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 21674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 21684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 216923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup.data(), 2170ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner DeclsInGroup.size()); 21714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 21724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 21737a614d8380297fcd2bc23986241905d97222948cRichard Smith/// ParseCXXMemberInitializer - Parse the brace-or-equal-initializer or 21747a614d8380297fcd2bc23986241905d97222948cRichard Smith/// pure-specifier. Also detect and reject any attempted defaulted/deleted 21757a614d8380297fcd2bc23986241905d97222948cRichard Smith/// function definition. The location of the '=', if any, will be placed in 21767a614d8380297fcd2bc23986241905d97222948cRichard Smith/// EqualLoc. 21777a614d8380297fcd2bc23986241905d97222948cRichard Smith/// 21787a614d8380297fcd2bc23986241905d97222948cRichard Smith/// pure-specifier: 21797a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '= 0' 218033deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// 21817a614d8380297fcd2bc23986241905d97222948cRichard Smith/// brace-or-equal-initializer: 21827a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '=' initializer-expression 218333deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// braced-init-list 218433deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// 21857a614d8380297fcd2bc23986241905d97222948cRichard Smith/// initializer-clause: 21867a614d8380297fcd2bc23986241905d97222948cRichard Smith/// assignment-expression 218733deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// braced-init-list 218833deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// 21897a614d8380297fcd2bc23986241905d97222948cRichard Smith/// defaulted/deleted function-definition: 21907a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '=' 'default' 21917a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '=' 'delete' 21927a614d8380297fcd2bc23986241905d97222948cRichard Smith/// 21937a614d8380297fcd2bc23986241905d97222948cRichard Smith/// Prior to C++0x, the assignment-expression in an initializer-clause must 21947a614d8380297fcd2bc23986241905d97222948cRichard Smith/// be a constant-expression. 2195552e29985a710f4ced62b39d70557501bd31ca9bDouglas GregorExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction, 21967a614d8380297fcd2bc23986241905d97222948cRichard Smith SourceLocation &EqualLoc) { 21977a614d8380297fcd2bc23986241905d97222948cRichard Smith assert((Tok.is(tok::equal) || Tok.is(tok::l_brace)) 21987a614d8380297fcd2bc23986241905d97222948cRichard Smith && "Data member initializer not starting with '=' or '{'"); 21997a614d8380297fcd2bc23986241905d97222948cRichard Smith 2200552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor EnterExpressionEvaluationContext Context(Actions, 2201552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor Sema::PotentiallyEvaluated, 2202552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor D); 22037a614d8380297fcd2bc23986241905d97222948cRichard Smith if (Tok.is(tok::equal)) { 22047a614d8380297fcd2bc23986241905d97222948cRichard Smith EqualLoc = ConsumeToken(); 22057a614d8380297fcd2bc23986241905d97222948cRichard Smith if (Tok.is(tok::kw_delete)) { 22067a614d8380297fcd2bc23986241905d97222948cRichard Smith // In principle, an initializer of '= delete p;' is legal, but it will 22077a614d8380297fcd2bc23986241905d97222948cRichard Smith // never type-check. It's better to diagnose it as an ill-formed expression 22087a614d8380297fcd2bc23986241905d97222948cRichard Smith // than as an ill-formed deleted non-function member. 22097a614d8380297fcd2bc23986241905d97222948cRichard Smith // An initializer of '= delete p, foo' will never be parsed, because 22107a614d8380297fcd2bc23986241905d97222948cRichard Smith // a top-level comma always ends the initializer expression. 22117a614d8380297fcd2bc23986241905d97222948cRichard Smith const Token &Next = NextToken(); 22127a614d8380297fcd2bc23986241905d97222948cRichard Smith if (IsFunction || Next.is(tok::semi) || Next.is(tok::comma) || 22137a614d8380297fcd2bc23986241905d97222948cRichard Smith Next.is(tok::eof)) { 22147a614d8380297fcd2bc23986241905d97222948cRichard Smith if (IsFunction) 22157a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) 22167a614d8380297fcd2bc23986241905d97222948cRichard Smith << 1 /* delete */; 22177a614d8380297fcd2bc23986241905d97222948cRichard Smith else 22187a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(ConsumeToken(), diag::err_deleted_non_function); 22197a614d8380297fcd2bc23986241905d97222948cRichard Smith return ExprResult(); 22207a614d8380297fcd2bc23986241905d97222948cRichard Smith } 22217a614d8380297fcd2bc23986241905d97222948cRichard Smith } else if (Tok.is(tok::kw_default)) { 22227a614d8380297fcd2bc23986241905d97222948cRichard Smith if (IsFunction) 22237a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(Tok, diag::err_default_delete_in_multiple_declaration) 22247a614d8380297fcd2bc23986241905d97222948cRichard Smith << 0 /* default */; 22257a614d8380297fcd2bc23986241905d97222948cRichard Smith else 22267a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(ConsumeToken(), diag::err_default_special_members); 22277a614d8380297fcd2bc23986241905d97222948cRichard Smith return ExprResult(); 22287a614d8380297fcd2bc23986241905d97222948cRichard Smith } 22297a614d8380297fcd2bc23986241905d97222948cRichard Smith 223033deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl } 223133deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl return ParseInitializer(); 22327a614d8380297fcd2bc23986241905d97222948cRichard Smith} 22337a614d8380297fcd2bc23986241905d97222948cRichard Smith 22344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition. 22354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 22364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-specification: 22374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declaration member-specification[opt] 22384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// access-specifier ':' member-specification[opt] 22394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 224017d35c36fbae764fcd68fa8b31624078a033aabcJoao Matosvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, 224117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos unsigned TagType, Decl *TagDecl) { 224217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos assert((TagType == DeclSpec::TST_struct || 224317d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType == DeclSpec::TST_interface || 224417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType == DeclSpec::TST_union || 224517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType == DeclSpec::TST_class) && "Invalid TagType!"); 224617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos 2247f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc, 2248f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall "parsing struct/union/class body"); 22491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 225026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // Determine whether this is a non-nested class. Note that local 225126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // classes are *not* considered to be nested classes. 225226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor bool NonNestedClass = true; 225326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (!ClassStack.empty()) { 225423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor for (const Scope *S = getCurScope(); S; S = S->getParent()) { 225526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (S->isClassScope()) { 225626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // We're inside a class scope, so this is a nested class. 225726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor NonNestedClass = false; 225826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor break; 225926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 226026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor 226126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if ((S->getFlags() & Scope::FnScope)) { 226226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // If we're in a function or function template declared in the 226326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // body of a class, then this is a local class rather than a 226426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // nested class. 226526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor const Scope *Parent = S->getParent(); 226626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (Parent->isTemplateParamScope()) 226726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor Parent = Parent->getParent(); 226826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (Parent->isClassScope()) 226926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor break; 227026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 227126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 227226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 22734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 22744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Enter a scope for the class. 22753218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope); 22764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 22776569d68745c8213709740337d2be52b031384f58Douglas Gregor // Note that we are parsing a new (potentially-nested) class definition. 227826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass); 22796569d68745c8213709740337d2be52b031384f58Douglas Gregor 2280ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor if (TagDecl) 228123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); 2282bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 2283b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson SourceLocation FinalLoc; 2284b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson 2285b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson // Parse the optional 'final' keyword. 22864e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) { 22878b11b5e6ce086fcaa7344bf84cffefcf4b53f9f6Richard Smith assert(isCXX0XFinalKeyword() && "not a class definition"); 22888b11b5e6ce086fcaa7344bf84cffefcf4b53f9f6Richard Smith FinalLoc = ConsumeToken(); 2289b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson 22904e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Diag(FinalLoc, getLangOpts().CPlusPlus0x ? 22917fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_override_control_keyword : 22927fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::ext_override_control_keyword) << "final"; 2293b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson } 2294cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 2295bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall if (Tok.is(tok::colon)) { 2296bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall ParseBaseClause(TagDecl); 2297bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 2298bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall if (!Tok.is(tok::l_brace)) { 2299bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall Diag(Tok, diag::err_expected_lbrace_after_base_specifiers); 2300db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall 2301db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall if (TagDecl) 230223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnTagDefinitionError(getCurScope(), TagDecl); 2303bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall return; 2304bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall } 2305bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall } 2306bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 2307bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall assert(Tok.is(tok::l_brace)); 23084a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_brace); 23094a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 2310bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 231142a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall if (TagDecl) 23122c3ee54e51d835a35bbf781c69e17f39e2ba0480Anders Carlsson Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc, 23134a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getOpenLocation()); 2314f9368159334ff86ea5fa367225c1a580977f3b03John McCall 23154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // C++ 11p3: Members of a class defined with the keyword class are private 23164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // by default. Members of a class defined with the keywords struct or union 23174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // are public by default. 23184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AccessSpecifier CurAS; 23194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (TagType == DeclSpec::TST_class) 23204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS_private; 23214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis else 23224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS_public; 23235f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParsedAttributes AccessAttrs(AttrFactory); 23244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 232507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (TagDecl) { 232607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // While we still have something to read, read the member-declarations. 232707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 232807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Each iteration of this loop reads one member-declaration. 232907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor 23304e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) || 2331563a645de82231a55e221fe655b7188bf8369662Francois Pichet Tok.is(tok::kw___if_not_exists))) { 2332563a645de82231a55e221fe655b7188bf8369662Francois Pichet ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS); 2333563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 2334563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 2335563a645de82231a55e221fe655b7188bf8369662Francois Pichet 233607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Check for extraneous top-level semicolon. 233707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (Tok.is(tok::semi)) { 2338eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith ConsumeExtraSemi(InsideStruct, TagType); 233907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor continue; 234007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } 23411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2342aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman if (Tok.is(tok::annot_pragma_vis)) { 2343aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman HandlePragmaVisibility(); 2344aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman continue; 2345aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman } 2346aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman 2347aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman if (Tok.is(tok::annot_pragma_pack)) { 2348aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman HandlePragmaPack(); 2349aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman continue; 2350aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman } 2351aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman 235207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor AccessSpecifier AS = getAccessSpecifierIfPresent(); 235307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (AS != AS_none) { 235407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Current token is a C++ access specifier. 235507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor CurAS = AS; 235607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor SourceLocation ASLoc = Tok.getLocation(); 235713f8daf70637f8f295134ac8e089dd7721e09085David Blaikie unsigned TokLength = Tok.getLength(); 235807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor ConsumeToken(); 23595f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen AccessAttrs.clear(); 23605f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen MaybeParseGNUAttributes(AccessAttrs); 23615f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen 236213f8daf70637f8f295134ac8e089dd7721e09085David Blaikie SourceLocation EndLoc; 236313f8daf70637f8f295134ac8e089dd7721e09085David Blaikie if (Tok.is(tok::colon)) { 236413f8daf70637f8f295134ac8e089dd7721e09085David Blaikie EndLoc = Tok.getLocation(); 236513f8daf70637f8f295134ac8e089dd7721e09085David Blaikie ConsumeToken(); 236613f8daf70637f8f295134ac8e089dd7721e09085David Blaikie } else if (Tok.is(tok::semi)) { 236713f8daf70637f8f295134ac8e089dd7721e09085David Blaikie EndLoc = Tok.getLocation(); 236813f8daf70637f8f295134ac8e089dd7721e09085David Blaikie ConsumeToken(); 236913f8daf70637f8f295134ac8e089dd7721e09085David Blaikie Diag(EndLoc, diag::err_expected_colon) 237013f8daf70637f8f295134ac8e089dd7721e09085David Blaikie << FixItHint::CreateReplacement(EndLoc, ":"); 237113f8daf70637f8f295134ac8e089dd7721e09085David Blaikie } else { 237213f8daf70637f8f295134ac8e089dd7721e09085David Blaikie EndLoc = ASLoc.getLocWithOffset(TokLength); 237313f8daf70637f8f295134ac8e089dd7721e09085David Blaikie Diag(EndLoc, diag::err_expected_colon) 237413f8daf70637f8f295134ac8e089dd7721e09085David Blaikie << FixItHint::CreateInsertion(EndLoc, ":"); 237513f8daf70637f8f295134ac8e089dd7721e09085David Blaikie } 2376c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen 2377c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen if (Actions.ActOnAccessSpecifier(AS, ASLoc, EndLoc, 2378c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen AccessAttrs.getList())) { 2379c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen // found another attribute than only annotations 2380c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen AccessAttrs.clear(); 2381c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen } 2382c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen 238307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor continue; 238407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } 23854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 238607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // FIXME: Make sure we don't have a template here. 23874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 238807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Parse all the comma separated declarators. 23895f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParseCXXClassMemberDeclaration(CurAS, AccessAttrs.getList()); 239007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } 23911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 23924a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 239307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } else { 239407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor SkipUntil(tok::r_brace, false, false); 23954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 23961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 23974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If attributes exist after class contents, parse them. 23980b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributes attrs(AttrFactory); 23997f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseGNUAttributes(attrs); 24004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 240142a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall if (TagDecl) 240223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl, 24034a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getOpenLocation(), 24044a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation(), 24057f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall attrs.getList()); 24064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 240774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // C++11 [class.mem]p2: 240874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Within the class member-specification, the class is regarded as complete 2409a058fd4f0a944174295f77169b438510dad389f8Richard Smith // within function bodies, default arguments, and 241074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // brace-or-equal-initializers for non-static data members (including such 241174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // things in nested classes). 241207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (TagDecl && NonNestedClass) { 24134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // We are not inside a nested class. This class and its nested classes 241472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // are complete and we can parse the delayed portions of method 2415eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // declarations and the lexed inline method definitions, along with any 2416eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // delayed attributes. 2417e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor SourceLocation SavedPrevTokLocation = PrevTokLocation; 2418eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski ParseLexedAttributes(getCurrentClass()); 24196569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseLexedMethodDeclarations(getCurrentClass()); 2420a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith 2421a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith // We've finished with all pending member declarations. 2422a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith Actions.ActOnFinishCXXMemberDecls(); 2423a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith 24247a614d8380297fcd2bc23986241905d97222948cRichard Smith ParseLexedMemberInitializers(getCurrentClass()); 24256569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseLexedMethodDefs(getCurrentClass()); 2426e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor PrevTokLocation = SavedPrevTokLocation; 24274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 24284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 242942a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall if (TagDecl) 24304a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, 24314a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 2432db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall 24334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Leave the class scope. 24346569d68745c8213709740337d2be52b031384f58Douglas Gregor ParsingDef.Pop(); 24358935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ClassScope.Exit(); 24364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 24377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 24387ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer, 24397ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a 24407ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers 24417ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below: 24427ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 24437ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code 24447ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { }; 24457ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base { 24467ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// int x; 24477ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// float f; 24487ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public: 24497ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// Derived(float f) : Base(), x(17), f(f) { } 24507ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// }; 24517ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode 24527ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 24531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++] ctor-initializer: 24541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ':' mem-initializer-list 24557ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 24561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++] mem-initializer-list: 24573fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor/// mem-initializer ...[opt] 24583fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor/// mem-initializer ...[opt] , mem-initializer-list 2459d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseConstructorInitializer(Decl *ConstructorDecl) { 24607ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'"); 24617ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 246228bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley // Poison the SEH identifiers so they are flagged as illegal in constructor initializers 246328bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true); 24647ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation ColonLoc = ConsumeToken(); 24651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 24665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CXXCtorInitializer*, 4> MemInitializers; 24679db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor bool AnyErrors = false; 2468193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 24697ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor do { 24700133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor if (Tok.is(tok::code_completion)) { 24710133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor Actions.CodeCompleteConstructorInitializer(ConstructorDecl, 24720133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor MemInitializers.data(), 24730133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor MemInitializers.size()); 24747d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return cutOffParsing(); 24750133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor } else { 24760133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); 24770133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor if (!MemInit.isInvalid()) 24780133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor MemInitializers.push_back(MemInit.get()); 24790133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor else 24800133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor AnyErrors = true; 24810133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor } 24820133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor 24837ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.is(tok::comma)) 24847ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor ConsumeToken(); 24857ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor else if (Tok.is(tok::l_brace)) 24867ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor break; 2487b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor // If the next token looks like a base or member initializer, assume that 2488b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor // we're just missing a comma. 2489751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor else if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) { 2490751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation); 2491751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor Diag(Loc, diag::err_ctor_init_missing_comma) 2492751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor << FixItHint::CreateInsertion(Loc, ", "); 2493751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor } else { 24947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Skip over garbage, until we get to '{'. Don't eat the '{'. 2495d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma); 24967ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SkipUntil(tok::l_brace, true, true); 24977ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor break; 24987ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 24997ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } while (true); 25007ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 25011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, 25029db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor MemInitializers.data(), MemInitializers.size(), 25039db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor AnyErrors); 25047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor} 25057ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 25067ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is 25077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one 25087ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See 25097ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example. 25107ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 25117ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer: 25127ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// mem-initializer-id '(' expression-list[opt] ')' 2513dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// [C++0x] mem-initializer-id braced-init-list 25141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 25157ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id: 25167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// '::'[opt] nested-name-specifier[opt] class-name 25177ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// identifier 2518d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) { 2519bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian // parse '::'[opt] nested-name-specifier[opt] 2520bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian CXXScopeSpec SS; 2521efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 2522b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TemplateTypeTy; 2523961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian if (Tok.is(tok::annot_template_id)) { 252425a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 2525d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor if (TemplateId->Kind == TNK_Type_template || 2526d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor TemplateId->Kind == TNK_Dependent_template_name) { 2527059101f922de6eb765601459925f4c8914420b23Douglas Gregor AnnotateTemplateIdTokenAsType(); 2528961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); 2529b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall TemplateTypeTy = getTypeAnnotation(Tok); 2530961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian } 2531961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian } 2532f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // Uses of decltype will already have been converted to annot_decltype by 2533f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // ParseOptionalCXXScopeSpecifier at this point. 2534f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie if (!TemplateTypeTy && Tok.isNot(tok::identifier) 2535f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie && Tok.isNot(tok::annot_decltype)) { 25361ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_member_or_base_name); 25377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor return true; 25387ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 25391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2540f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie IdentifierInfo *II = 0; 2541f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie DeclSpec DS(AttrFactory); 2542f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie SourceLocation IdLoc = Tok.getLocation(); 2543f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie if (Tok.is(tok::annot_decltype)) { 2544f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // Get the decltype expression, if there is one. 2545f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie ParseDecltypeSpecifier(DS); 2546f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie } else { 2547f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie if (Tok.is(tok::identifier)) 2548f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // Get the identifier. This may be a member name or a class name, 2549f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // but we'll let the semantic analysis determine which it is. 2550f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie II = Tok.getIdentifierInfo(); 2551f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie ConsumeToken(); 2552f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie } 2553f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie 25547ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 25557ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Parse the '('. 25564e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) { 25577fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 25587fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 25596df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl ExprResult InitList = ParseBraceInitializer(); 25606df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl if (InitList.isInvalid()) 25616df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl return true; 25626df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl 25636df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl SourceLocation EllipsisLoc; 25646df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl if (Tok.is(tok::ellipsis)) 25656df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl EllipsisLoc = ConsumeToken(); 25666df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl 25676df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II, 2568f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie TemplateTypeTy, DS, IdLoc, 2569f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie InitList.take(), EllipsisLoc); 2570dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } else if(Tok.is(tok::l_paren)) { 25714a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 25724a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 2573dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl 2574dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl // Parse the optional expression-list. 25754e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer ExprVector ArgExprs; 2576dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl CommaLocsTy CommaLocs; 2577dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) { 2578dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl SkipUntil(tok::r_paren); 2579dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return true; 2580dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } 25817ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 25824a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 25837ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 2584dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl SourceLocation EllipsisLoc; 2585dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (Tok.is(tok::ellipsis)) 2586dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl EllipsisLoc = ConsumeToken(); 25877ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 2588dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II, 2589f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie TemplateTypeTy, DS, IdLoc, 25904e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer T.getOpenLocation(), ArgExprs.data(), 25914a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor ArgExprs.size(), T.getCloseLocation(), 2592dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl EllipsisLoc); 2593dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } 2594dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl 25954e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie Diag(Tok, getLangOpts().CPlusPlus0x ? diag::err_expected_lparen_or_lbrace 2596dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl : diag::err_expected_lparen); 2597dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return true; 25987ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor} 25990fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 26007acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// \brief Parse a C++ exception-specification if present (C++0x [except.spec]). 26010fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 2602a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// exception-specification: 26037acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification 26047acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// noexcept-specification 26057acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 26067acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// noexcept-specification: 26077acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 'noexcept' 26087acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 'noexcept' '(' constant-expression ')' 26097acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType 2610a058fd4f0a944174295f77169b438510dad389f8Richard SmithParser::tryParseExceptionSpecification( 261174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor SourceRange &SpecificationRange, 26125f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<ParsedType> &DynamicExceptions, 26135f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<SourceRange> &DynamicExceptionRanges, 2614a058fd4f0a944174295f77169b438510dad389f8Richard Smith ExprResult &NoexceptExpr) { 26157acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl ExceptionSpecificationType Result = EST_None; 2616a058fd4f0a944174295f77169b438510dad389f8Richard Smith 26177acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // See if there's a dynamic specification. 26187acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.is(tok::kw_throw)) { 26197acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Result = ParseDynamicExceptionSpecification(SpecificationRange, 26207acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl DynamicExceptions, 26217acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl DynamicExceptionRanges); 26227acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl assert(DynamicExceptions.size() == DynamicExceptionRanges.size() && 26237acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl "Produced different number of exception types and ranges."); 26247acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 26257acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 26267acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // If there's no noexcept specification, we're done. 26277acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.isNot(tok::kw_noexcept)) 26287acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl return Result; 26297acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 2630841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith Diag(Tok, diag::warn_cxx98_compat_noexcept_decl); 2631841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith 26327acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // If we already had a dynamic specification, parse the noexcept for, 26337acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // recovery, but emit a diagnostic and don't store the results. 26347acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SourceRange NoexceptRange; 26357acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl ExceptionSpecificationType NoexceptType = EST_None; 26367acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 26377acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SourceLocation KeywordLoc = ConsumeToken(); 26387acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.is(tok::l_paren)) { 26397acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // There is an argument. 26404a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 26414a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 26427acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptType = EST_ComputedNoexcept; 26437acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptExpr = ParseConstantExpression(); 264460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // The argument must be contextually convertible to bool. We use 264560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // ActOnBooleanCondition for this purpose. 264660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (!NoexceptExpr.isInvalid()) 264760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NoexceptExpr = Actions.ActOnBooleanCondition(getCurScope(), KeywordLoc, 264860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NoexceptExpr.get()); 26494a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 26504a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation()); 26517acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } else { 26527acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // There is no argument. 26537acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptType = EST_BasicNoexcept; 26547acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptRange = SourceRange(KeywordLoc, KeywordLoc); 26557acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 26567acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 26577acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Result == EST_None) { 26587acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SpecificationRange = NoexceptRange; 26597acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Result = NoexceptType; 26607acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 26617acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // If there's a dynamic specification after a noexcept specification, 26627acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // parse that and ignore the results. 26637acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.is(tok::kw_throw)) { 26647acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification); 26657acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions, 26667acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl DynamicExceptionRanges); 26677acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 26687acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } else { 26697acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification); 26707acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 26717acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 26727acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl return Result; 26737acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl} 26747acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 26757acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// ParseDynamicExceptionSpecification - Parse a C++ 26767acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification (C++ [except.spec]). 26777acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 26787acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification: 2679a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// 'throw' '(' type-id-list [opt] ')' 2680a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS] 'throw' '(' '...' ')' 26811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 2682a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// type-id-list: 2683a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor/// type-id ... [opt] 2684a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor/// type-id-list ',' type-id ... [opt] 26850fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 26867acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType Parser::ParseDynamicExceptionSpecification( 26877acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SourceRange &SpecificationRange, 26885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<ParsedType> &Exceptions, 26895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<SourceRange> &Ranges) { 26900fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor assert(Tok.is(tok::kw_throw) && "expected throw"); 26911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26927acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SpecificationRange.setBegin(ConsumeToken()); 26934a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 26944a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.consumeOpen()) { 26957acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Diag(Tok, diag::err_expected_lparen_after) << "throw"; 26967acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SpecificationRange.setEnd(SpecificationRange.getBegin()); 269760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return EST_DynamicNone; 26980fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor } 26990fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 2700a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor // Parse throw(...), a Microsoft extension that means "this function 2701a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor // can throw anything". 2702a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor if (Tok.is(tok::ellipsis)) { 2703a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor SourceLocation EllipsisLoc = ConsumeToken(); 27044e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().MicrosoftExt) 2705a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec); 27064a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 27074a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SpecificationRange.setEnd(T.getCloseLocation()); 270860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return EST_MSAny; 2709a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor } 2710a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor 27110fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor // Parse the sequence of type-ids. 2712ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl SourceRange Range; 27130fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor while (Tok.isNot(tok::r_paren)) { 2714ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl TypeResult Res(ParseTypeName(&Range)); 27157acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 2716a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor if (Tok.is(tok::ellipsis)) { 2717a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor // C++0x [temp.variadic]p5: 2718a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor // - In a dynamic-exception-specification (15.4); the pattern is a 2719a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor // type-id. 2720a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor SourceLocation Ellipsis = ConsumeToken(); 27217acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Range.setEnd(Ellipsis); 2722a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor if (!Res.isInvalid()) 2723a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor Res = Actions.ActOnPackExpansion(Res.get(), Ellipsis); 2724a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor } 27257acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 2726ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl if (!Res.isInvalid()) { 27277dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl Exceptions.push_back(Res.get()); 2728ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl Ranges.push_back(Range); 2729ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl } 2730a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor 27310fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor if (Tok.is(tok::comma)) 27320fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor ConsumeToken(); 27337dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl else 27340fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor break; 27350fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor } 27360fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 27374a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 27384a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SpecificationRange.setEnd(T.getCloseLocation()); 273960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic; 27400fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor} 27416569d68745c8213709740337d2be52b031384f58Douglas Gregor 2742dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// ParseTrailingReturnType - Parse a trailing return type on a new-style 2743dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// function declaration. 2744ae7902c4293d9de8b9591759513f0d075f45022aDouglas GregorTypeResult Parser::ParseTrailingReturnType(SourceRange &Range) { 2745dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor assert(Tok.is(tok::arrow) && "expected arrow"); 2746dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor 2747dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor ConsumeToken(); 2748dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor 27497796eb5643244f3134834253ce5ea89107ac21c1Richard Smith return ParseTypeName(&Range, Declarator::TrailingReturnContext); 2750dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor} 2751dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor 27526569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief We have just started parsing the definition of a new class, 27536569d68745c8213709740337d2be52b031384f58Douglas Gregor/// so push that class onto our stack of classes that is currently 27546569d68745c8213709740337d2be52b031384f58Douglas Gregor/// being parsed. 2755eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallSema::ParsingClassState 2756eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallParser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass) { 275726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor assert((NonNestedClass || !ClassStack.empty()) && 27586569d68745c8213709740337d2be52b031384f58Douglas Gregor "Nested class without outer class"); 275926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass)); 2760eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall return Actions.PushParsingClass(); 27616569d68745c8213709740337d2be52b031384f58Douglas Gregor} 27626569d68745c8213709740337d2be52b031384f58Douglas Gregor 27636569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Deallocate the given parsed class and all of its nested 27646569d68745c8213709740337d2be52b031384f58Douglas Gregor/// classes. 27656569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) { 2766d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I) 2767d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor delete Class->LateParsedDeclarations[I]; 27686569d68745c8213709740337d2be52b031384f58Douglas Gregor delete Class; 27696569d68745c8213709740337d2be52b031384f58Douglas Gregor} 27706569d68745c8213709740337d2be52b031384f58Douglas Gregor 27716569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Pop the top class of the stack of classes that are 27726569d68745c8213709740337d2be52b031384f58Douglas Gregor/// currently being parsed. 27736569d68745c8213709740337d2be52b031384f58Douglas Gregor/// 27746569d68745c8213709740337d2be52b031384f58Douglas Gregor/// This routine should be called when we have finished parsing the 27756569d68745c8213709740337d2be52b031384f58Douglas Gregor/// definition of a class, but have not yet popped the Scope 27766569d68745c8213709740337d2be52b031384f58Douglas Gregor/// associated with the class's definition. 2777eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Parser::PopParsingClass(Sema::ParsingClassState state) { 27786569d68745c8213709740337d2be52b031384f58Douglas Gregor assert(!ClassStack.empty() && "Mismatched push/pop for class parsing"); 27791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2780eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall Actions.PopParsingClass(state); 2781eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 27826569d68745c8213709740337d2be52b031384f58Douglas Gregor ParsingClass *Victim = ClassStack.top(); 27836569d68745c8213709740337d2be52b031384f58Douglas Gregor ClassStack.pop(); 27846569d68745c8213709740337d2be52b031384f58Douglas Gregor if (Victim->TopLevelClass) { 27856569d68745c8213709740337d2be52b031384f58Douglas Gregor // Deallocate all of the nested classes of this class, 27866569d68745c8213709740337d2be52b031384f58Douglas Gregor // recursively: we don't need to keep any of this information. 27876569d68745c8213709740337d2be52b031384f58Douglas Gregor DeallocateParsedClasses(Victim); 27886569d68745c8213709740337d2be52b031384f58Douglas Gregor return; 27891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 27906569d68745c8213709740337d2be52b031384f58Douglas Gregor assert(!ClassStack.empty() && "Missing top-level class?"); 27916569d68745c8213709740337d2be52b031384f58Douglas Gregor 2792d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (Victim->LateParsedDeclarations.empty()) { 27936569d68745c8213709740337d2be52b031384f58Douglas Gregor // The victim is a nested class, but we will not need to perform 27946569d68745c8213709740337d2be52b031384f58Douglas Gregor // any processing after the definition of this class since it has 27956569d68745c8213709740337d2be52b031384f58Douglas Gregor // no members whose handling was delayed. Therefore, we can just 27966569d68745c8213709740337d2be52b031384f58Douglas Gregor // remove this nested class. 2797d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor DeallocateParsedClasses(Victim); 27986569d68745c8213709740337d2be52b031384f58Douglas Gregor return; 27996569d68745c8213709740337d2be52b031384f58Douglas Gregor } 28006569d68745c8213709740337d2be52b031384f58Douglas Gregor 28016569d68745c8213709740337d2be52b031384f58Douglas Gregor // This nested class has some members that will need to be processed 28026569d68745c8213709740337d2be52b031384f58Douglas Gregor // after the top-level class is completely defined. Therefore, add 28036569d68745c8213709740337d2be52b031384f58Douglas Gregor // it to the list of nested classes within its parent. 280423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor assert(getCurScope()->isClassScope() && "Nested class outside of class scope?"); 2805d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ClassStack.top()->LateParsedDeclarations.push_back(new LateParsedClass(this, Victim)); 280623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope(); 28076569d68745c8213709740337d2be52b031384f58Douglas Gregor} 2808bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2809c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// \brief Try to parse an 'identifier' which appears within an attribute-token. 2810c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// 2811c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// \return the parsed identifier on success, and 0 if the next token is not an 2812c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute-token. 2813c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// 2814c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// C++11 [dcl.attr.grammar]p3: 2815c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// If a keyword or an alternative token that satisfies the syntactic 2816c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// requirements of an identifier is contained in an attribute-token, 2817c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// it is considered an identifier. 2818c56298d87a9df507805a548d7d515e8b511df2c0Richard SmithIdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(SourceLocation &Loc) { 2819c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith switch (Tok.getKind()) { 2820c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith default: 2821c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // Identifiers and keywords have identifier info attached. 2822c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (IdentifierInfo *II = Tok.getIdentifierInfo()) { 2823c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith Loc = ConsumeToken(); 2824c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith return II; 2825c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 2826c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith return 0; 2827c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 2828c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::ampamp: // 'and' 2829c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::pipe: // 'bitor' 2830c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::pipepipe: // 'or' 2831c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::caret: // 'xor' 2832c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::tilde: // 'compl' 2833c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::amp: // 'bitand' 2834c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::ampequal: // 'and_eq' 2835c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::pipeequal: // 'or_eq' 2836c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::caretequal: // 'xor_eq' 2837c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::exclaim: // 'not' 2838c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::exclaimequal: // 'not_eq' 2839c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // Alternative tokens do not have identifier info, but their spelling 2840c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // starts with an alphabetical character. 2841c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith llvm::SmallString<8> SpellingBuf; 2842c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith StringRef Spelling = PP.getSpelling(Tok.getLocation(), SpellingBuf); 2843c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (std::isalpha(Spelling[0])) { 2844c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith Loc = ConsumeToken(); 28450eb7526cd2524af78fb9a2a2522045fb25fc3d27Benjamin Kramer return &PP.getIdentifierTable().get(Spelling); 2846c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 2847c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith return 0; 2848c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 2849c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith} 2850c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 2851c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier. Currently 28523497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// only parses standard attributes. 2853bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28546ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-specifier: 2855bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '[' '[' attribute-list ']' ']' 285682d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne/// alignment-specifier 2857bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28586ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-list: 2859bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute[opt] 2860bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-list ',' attribute[opt] 2861c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute '...' 2862c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute-list ',' attribute '...' 2863bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28646ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute: 2865bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-token attribute-argument-clause[opt] 2866bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28676ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-token: 2868bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// identifier 2869bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-scoped-token 2870bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28716ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-scoped-token: 2872bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-namespace '::' identifier 2873bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28746ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-namespace: 2875bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// identifier 2876bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28776ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-argument-clause: 2878bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '(' balanced-token-seq ')' 2879bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28806ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] balanced-token-seq: 2881bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// balanced-token 2882bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// balanced-token-seq balanced-token 2883bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 28846ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] balanced-token: 2885bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '(' balanced-token-seq ')' 2886bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '[' balanced-token-seq ']' 2887bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '{' balanced-token-seq '}' 2888bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// any token but '(', ')', '[', ']', '{', or '}' 2889c56298d87a9df507805a548d7d515e8b511df2c0Richard Smithvoid Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs, 28903497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne SourceLocation *endLoc) { 289182d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne if (Tok.is(tok::kw_alignas)) { 289241be673e93ed225b45479557b20ff19b3082bae8Richard Smith Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas); 289382d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne ParseAlignmentSpecifier(attrs, endLoc); 289482d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne return; 289582d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne } 289682d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne 2897bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square) 28986ee326af4e77e6f05973486097884d7431f2108dRichard Smith && "Not a C++11 attribute list"); 2899bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 290041be673e93ed225b45479557b20ff19b3082bae8Richard Smith Diag(Tok.getLocation(), diag::warn_cxx98_compat_attribute); 290141be673e93ed225b45479557b20ff19b3082bae8Richard Smith 2902bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeBracket(); 2903bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeBracket(); 2904193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 2905c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith while (Tok.isNot(tok::r_square)) { 2906bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // attribute not present 2907bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.is(tok::comma)) { 2908bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeToken(); 2909bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt continue; 2910bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2911bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2912c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith SourceLocation ScopeLoc, AttrLoc; 2913c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith IdentifierInfo *ScopeName = 0, *AttrName = 0; 2914c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 2915c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith AttrName = TryParseCXX11AttributeIdentifier(AttrLoc); 2916c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (!AttrName) 2917c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // Break out to the "expected ']'" diagnostic. 2918c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith break; 2919193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 2920bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // scoped attribute 2921bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.is(tok::coloncolon)) { 2922bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeToken(); 2923bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2924c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith ScopeName = AttrName; 2925c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith ScopeLoc = AttrLoc; 2926c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 2927c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith AttrName = TryParseCXX11AttributeIdentifier(AttrLoc); 2928c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (!AttrName) { 2929bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt Diag(Tok.getLocation(), diag::err_expected_ident); 2930bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_square, tok::comma, true, true); 2931bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt continue; 2932bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2933bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2934bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2935bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt bool AttrParsed = false; 293693f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt switch (AttributeList::getKind(AttrName, ScopeName, 293793f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt AttributeList::AS_CXX11)) { 2938e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // No arguments 29398e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_CarriesDependency: 2940e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // FIXME: implement generic support of attributes with C++11 syntax 2941e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // see Parse/ParseDecl.cpp: ParseGNUAttributes 29428e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_FallThrough: 29438e083e71d48f7f4d6ef40c00531c2e14df745486Sean Hunt case AttributeList::AT_NoReturn: { 2944e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith if (Tok.is(tok::l_paren)) { 2945e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith Diag(Tok.getLocation(), diag::err_cxx11_attribute_forbids_arguments) 2946e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith << AttrName->getName(); 2947bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt break; 2948bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2949bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2950e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith attrs.addNew(AttrName, 2951e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, 2952e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith AttrLoc), 2953e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith ScopeName, ScopeLoc, 0, 295493f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt SourceLocation(), 0, 0, AttributeList::AS_CXX11); 2955e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith AttrParsed = true; 2956e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith break; 2957e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith } 2958e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith 2959e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith // Silence warnings 2960e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith default: break; 2961bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2962bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2963bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // Skip the entire parameter clause, if any 2964bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (!AttrParsed && Tok.is(tok::l_paren)) { 2965bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeParen(); 2966bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // SkipUntil maintains the balancedness of tokens. 2967bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_paren, false); 2968bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 29696ee326af4e77e6f05973486097884d7431f2108dRichard Smith 2970c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (Tok.is(tok::ellipsis)) { 2971c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (AttrParsed) 2972c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) 2973c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith << AttrName->getName(); 29746ee326af4e77e6f05973486097884d7431f2108dRichard Smith ConsumeToken(); 2975c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 2976bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 2977bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2978bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare)) 2979bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_square, false); 29803497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne if (endLoc) 29813497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne *endLoc = Tok.getLocation(); 2982bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare)) 2983bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_square, false); 29843497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne} 29853497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne 29862edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt/// ParseCXX11Attributes - Parse a C++11 attribute-specifier-seq. 29873497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// 29883497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// attribute-specifier-seq: 29893497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// attribute-specifier-seq[opt] attribute-specifier 2990c56298d87a9df507805a548d7d515e8b511df2c0Richard Smithvoid Parser::ParseCXX11Attributes(ParsedAttributesWithRange &attrs, 29913497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne SourceLocation *endLoc) { 29923497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne SourceLocation StartLoc = Tok.getLocation(), Loc; 29933497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne if (!endLoc) 29943497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne endLoc = &Loc; 29953497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne 29968828ee7faa42f889ade3bb635dc5f1338be671b1Douglas Gregor do { 2997c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith ParseCXX11AttributeSpecifier(attrs, endLoc); 29986ee326af4e77e6f05973486097884d7431f2108dRichard Smith } while (isCXX11AttributeSpecifier()); 2999bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 30003497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne attrs.Range = SourceRange(StartLoc, *endLoc); 3001bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 3002bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 3003334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ParseMicrosoftAttributes - Parse a Microsoft attribute [Attr] 3004334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// 3005334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute: 3006334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// '[' token-seq ']' 3007334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// 3008334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute-seq: 3009334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ms-attribute[opt] 3010334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ms-attribute ms-attribute-seq 30117f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCallvoid Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs, 30127f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall SourceLocation *endLoc) { 3013334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list"); 3014334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet 3015334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet while (Tok.is(tok::l_square)) { 30166ee326af4e77e6f05973486097884d7431f2108dRichard Smith // FIXME: If this is actually a C++11 attribute, parse it as one. 3017334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet ConsumeBracket(); 3018334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet SkipUntil(tok::r_square, true, true); 30197f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (endLoc) *endLoc = Tok.getLocation(); 3020334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); 3021334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet } 3022334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet} 3023563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3024563a645de82231a55e221fe655b7188bf8369662Francois Pichetvoid Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType, 3025563a645de82231a55e221fe655b7188bf8369662Francois Pichet AccessSpecifier& CurAS) { 30263896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor IfExistsCondition Result; 3027563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (ParseMicrosoftIfExistsCondition(Result)) 3028563a645de82231a55e221fe655b7188bf8369662Francois Pichet return; 3029563a645de82231a55e221fe655b7188bf8369662Francois Pichet 30303896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor BalancedDelimiterTracker Braces(*this, tok::l_brace); 30313896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor if (Braces.consumeOpen()) { 3032563a645de82231a55e221fe655b7188bf8369662Francois Pichet Diag(Tok, diag::err_expected_lbrace); 3033563a645de82231a55e221fe655b7188bf8369662Francois Pichet return; 3034563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3035563a645de82231a55e221fe655b7188bf8369662Francois Pichet 30363896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor switch (Result.Behavior) { 30373896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor case IEB_Parse: 30383896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor // Parse the declarations below. 30393896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor break; 30403896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor 30413896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor case IEB_Dependent: 30423896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists) 30433896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor << Result.IsIfExists; 30443896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor // Fall through to skip. 30453896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor 30463896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor case IEB_Skip: 30473896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor Braces.skipToEnd(); 3048563a645de82231a55e221fe655b7188bf8369662Francois Pichet return; 3049563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3050563a645de82231a55e221fe655b7188bf8369662Francois Pichet 30513896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 3052563a645de82231a55e221fe655b7188bf8369662Francois Pichet // __if_exists, __if_not_exists can nest. 3053563a645de82231a55e221fe655b7188bf8369662Francois Pichet if ((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists))) { 3054563a645de82231a55e221fe655b7188bf8369662Francois Pichet ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS); 3055563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 3056563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3057563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3058563a645de82231a55e221fe655b7188bf8369662Francois Pichet // Check for extraneous top-level semicolon. 3059563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (Tok.is(tok::semi)) { 3060eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith ConsumeExtraSemi(InsideStruct, TagType); 3061563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 3062563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3063563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3064563a645de82231a55e221fe655b7188bf8369662Francois Pichet AccessSpecifier AS = getAccessSpecifierIfPresent(); 3065563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (AS != AS_none) { 3066563a645de82231a55e221fe655b7188bf8369662Francois Pichet // Current token is a C++ access specifier. 3067563a645de82231a55e221fe655b7188bf8369662Francois Pichet CurAS = AS; 3068563a645de82231a55e221fe655b7188bf8369662Francois Pichet SourceLocation ASLoc = Tok.getLocation(); 3069563a645de82231a55e221fe655b7188bf8369662Francois Pichet ConsumeToken(); 3070563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (Tok.is(tok::colon)) 3071563a645de82231a55e221fe655b7188bf8369662Francois Pichet Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation()); 3072563a645de82231a55e221fe655b7188bf8369662Francois Pichet else 3073563a645de82231a55e221fe655b7188bf8369662Francois Pichet Diag(Tok, diag::err_expected_colon); 3074563a645de82231a55e221fe655b7188bf8369662Francois Pichet ConsumeToken(); 3075563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 3076563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3077563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3078563a645de82231a55e221fe655b7188bf8369662Francois Pichet // Parse all the comma separated declarators. 30795f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParseCXXClassMemberDeclaration(CurAS, 0); 3080563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 30813896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor 30823896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor Braces.consumeClose(); 3083563a645de82231a55e221fe655b7188bf8369662Francois Pichet} 3084