ParseDeclCXX.cpp revision c640058aa7f224a71ce3b1d2601d84e1b57f82d3
18f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -----------------------===// 28f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 38f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// The LLVM Compiler Infrastructure 48f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 78f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 88f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===----------------------------------------------------------------------===// 98f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 108f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// This file implements the C++ Declaration portions of the Parser interfaces. 118f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner// 128f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner//===----------------------------------------------------------------------===// 138f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 141b7f89846f10681ce3cbe89ef5d60691d55bd918Douglas Gregor#include "clang/Parse/Parser.h" 1555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "RAIIObjectsForParser.h" 163f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose#include "clang/Basic/CharInfo.h" 1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/OperatorKinds.h" 18500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h" 1919510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h" 2019510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/ParsedTemplate.h" 21f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall#include "clang/Sema/PrettyDeclStackTrace.h" 2255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Scope.h" 23e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall#include "clang/Sema/SemaDiagnostic.h" 248fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer#include "llvm/ADT/SmallString.h" 258f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattnerusing namespace clang; 268f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 278f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// ParseNamespace - We know that the current token is a namespace keyword. This 28d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// may either be a top level namespace or a block-level namespace alias. If 29d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// there was an inline keyword, it has already been parsed. 308f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 318f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// namespace-definition: [C++ 7.3: basic.namespace] 328f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// named-namespace-definition 338f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// unnamed-namespace-definition 348f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 358f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// unnamed-namespace-definition: 36d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// 'inline'[opt] 'namespace' attributes[opt] '{' namespace-body '}' 378f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 388f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// named-namespace-definition: 398f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// original-namespace-definition 408f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// extension-namespace-definition 418f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 428f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// original-namespace-definition: 43d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// 'inline'[opt] 'namespace' identifier attributes[opt] 44d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// '{' namespace-body '}' 458f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 468f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// extension-namespace-definition: 47d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// 'inline'[opt] 'namespace' original-namespace-name 48d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// '{' namespace-body '}' 491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 508f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// namespace-alias-definition: [C++ 7.3.2: namespace.alias] 518f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 'namespace' identifier '=' qualified-namespace-specifier ';' 528f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 53d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespace(unsigned Context, 54d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl SourceLocation &DeclEnd, 55d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl SourceLocation InlineLoc) { 5604d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner assert(Tok.is(tok::kw_namespace) && "Not a namespace!"); 578f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'. 589735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian ObjCDeclContextSwitch ObjCDC(*this); 59a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian 6049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor if (Tok.is(tok::code_completion)) { 6123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteNamespaceDecl(getCurScope()); 627d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 637d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return 0; 6449f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor } 65193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 668f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation IdentLoc; 678f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner IdentifierInfo *Ident = 0; 68f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<SourceLocation> ExtraIdentLoc; 69f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<IdentifierInfo*> ExtraIdent; 70f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<SourceLocation> ExtraNamespaceLoc; 716a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor 726a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor Token attrTok; 731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7404d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner if (Tok.is(tok::identifier)) { 758f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner Ident = Tok.getIdentifierInfo(); 768f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner IdentLoc = ConsumeToken(); // eat the identifier. 77f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu while (Tok.is(tok::coloncolon) && NextToken().is(tok::identifier)) { 78f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ExtraNamespaceLoc.push_back(ConsumeToken()); 79f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ExtraIdent.push_back(Tok.getIdentifierInfo()); 80f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ExtraIdentLoc.push_back(ConsumeToken()); 81f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 828f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner } 831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 848f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner // Read label attributes, if present. 850b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributes attrs(AttrFactory); 866a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor if (Tok.is(tok::kw___attribute)) { 876a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor attrTok = Tok; 887f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseGNUAttributes(attrs); 896a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor } 901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 916a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor if (Tok.is(tok::equal)) { 92e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber if (Ident == 0) { 93e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber Diag(Tok, diag::err_expected_ident); 94e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber // Skip to end of the definition and eat the ';'. 95e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber SkipUntil(tok::semi); 96e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber return 0; 97e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber } 987f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (!attrs.empty()) 996a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor Diag(attrTok, diag::err_unexpected_namespace_attributes_alias); 100d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl if (InlineLoc.isValid()) 101d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl Diag(InlineLoc, diag::err_inline_namespace_alias) 102d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl << FixItHint::CreateRemoval(InlineLoc); 1039735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd); 1046a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor } 1051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 106f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 1074a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_brace); 1084a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.consumeOpen()) { 109f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (!ExtraIdent.empty()) { 110f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon) 111f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back()); 112f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(Tok, Ident ? diag::err_expected_lbrace : 1145144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner diag::err_expected_ident_lbrace); 115d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 1165144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner } 1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() || 11923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor getCurScope()->isInObjcMethodScope() || getCurScope()->getBlockParent() || 12023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor getCurScope()->getFnParent()) { 121f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (!ExtraIdent.empty()) { 122f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon) 123f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back()); 124f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 1254a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope); 12695f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor SkipUntil(tok::r_brace, false); 127d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 12895f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor } 12995f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor 130f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (!ExtraIdent.empty()) { 131f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu TentativeParsingAction TPA(*this); 132f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu SkipUntil(tok::r_brace, /*StopAtSemi*/false, /*DontConsume*/true); 133f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Token rBraceToken = Tok; 134f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu TPA.Revert(); 135f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 136f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (!rBraceToken.is(tok::r_brace)) { 137f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon) 138f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back()); 139f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } else { 1409910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer std::string NamespaceFix; 141f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu for (std::vector<IdentifierInfo*>::iterator I = ExtraIdent.begin(), 142f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu E = ExtraIdent.end(); I != E; ++I) { 143f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceFix += " { namespace "; 144f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceFix += (*I)->getName(); 145f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 1469910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer 147f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::string RBraces; 1489910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer for (unsigned i = 0, e = ExtraIdent.size(); i != e; ++i) 149f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu RBraces += "} "; 1509910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer 151f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon) 152f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << FixItHint::CreateReplacement(SourceRange(ExtraNamespaceLoc.front(), 153f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ExtraIdentLoc.back()), 154f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceFix) 155f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << FixItHint::CreateInsertion(rBraceToken.getLocation(), RBraces); 156f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 157f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 158f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 15988e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl // If we're still good, complain about inline namespaces in non-C++0x now. 1607fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith if (InlineLoc.isValid()) 16180ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith Diag(InlineLoc, getLangOpts().CPlusPlus11 ? 1627fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_inline_namespace : diag::ext_inline_namespace); 16388e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl 1645144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner // Enter a scope for the namespace. 1655144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner ParseScope NamespaceScope(this, Scope::DeclScope); 1662d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 167d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl *NamespcDecl = 168acba90f30876b4140b738f0d3dd0e50724053a96Abramo Bagnara Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, NamespaceLoc, 1694a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor IdentLoc, Ident, T.getOpenLocation(), 1704a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor attrs.getList()); 1712d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 172f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc, 173f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall "parsing namespace"); 1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 175f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu // Parse the contents of the namespace. This includes parsing recovery on 176f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu // any improperly nested namespaces. 177f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParseInnerNamespace(ExtraIdentLoc, ExtraIdent, ExtraNamespaceLoc, 0, 1784a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor InlineLoc, attrs, T); 1791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1805144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner // Leave the namespace scope. 1815144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner NamespaceScope.Exit(); 1828ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis 1834a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor DeclEnd = T.getCloseLocation(); 1844a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Actions.ActOnFinishNamespaceDef(NamespcDecl, DeclEnd); 1852d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 1865144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner return NamespcDecl; 1878f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner} 188c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 189f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu/// ParseInnerNamespace - Parse the contents of a namespace. 190f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieuvoid Parser::ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc, 191f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<IdentifierInfo*>& Ident, 192f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<SourceLocation>& NamespaceLoc, 193f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu unsigned int index, SourceLocation& InlineLoc, 194f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParsedAttributes& attrs, 1954a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker &Tracker) { 196f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (index == Ident.size()) { 197f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 198f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParsedAttributesWithRange attrs(AttrFactory); 1994e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith MaybeParseCXX11Attributes(attrs); 200f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu MaybeParseMicrosoftAttributes(attrs); 201f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParseExternalDeclaration(attrs); 202f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 2034a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor 2044a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor // The caller is what called check -- we are simply calling 2054a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor // the close for it. 2064a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.consumeClose(); 207f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 208f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu return; 209f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 210f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 211f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu // Parse improperly nested namespaces. 212f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParseScope NamespaceScope(this, Scope::DeclScope); 213f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Decl *NamespcDecl = 214f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Actions.ActOnStartNamespaceDef(getCurScope(), SourceLocation(), 215f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceLoc[index], IdentLoc[index], 2164a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Ident[index], Tracker.getOpenLocation(), 2174a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor attrs.getList()); 218f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 219f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParseInnerNamespace(IdentLoc, Ident, NamespaceLoc, ++index, InlineLoc, 2204a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor attrs, Tracker); 221f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 222f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceScope.Exit(); 223f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 2244a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Actions.ActOnFinishNamespaceDef(NamespcDecl, Tracker.getCloseLocation()); 225f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu} 226f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 227f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// ParseNamespaceAlias - Parse the part after the '=' in a namespace 228f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// alias definition. 229f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// 230d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc, 2310b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall SourceLocation AliasLoc, 2320b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall IdentifierInfo *Alias, 2330b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall SourceLocation &DeclEnd) { 234f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson assert(Tok.is(tok::equal) && "Not equal token"); 2351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 236f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson ConsumeToken(); // eat the '='. 2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 23849f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor if (Tok.is(tok::code_completion)) { 23923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteNamespaceAliasDecl(getCurScope()); 2407d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 2417d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return 0; 24249f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor } 243193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 244f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson CXXScopeSpec SS; 245f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson // Parse (optional) nested-name-specifier. 246efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 247f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson 248f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson if (SS.isInvalid() || Tok.isNot(tok::identifier)) { 249f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson Diag(Tok, diag::err_expected_namespace_name); 250f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson // Skip to end of the definition and eat the ';'. 251f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson SkipUntil(tok::semi); 252d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 253f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson } 254f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson 255f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson // Parse identifier. 25603bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson IdentifierInfo *Ident = Tok.getIdentifierInfo(); 25703bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson SourceLocation IdentLoc = ConsumeToken(); 2581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 259f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson // Eat the ';'. 26097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner DeclEnd = Tok.getLocation(); 2616869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name, 2626869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner "", tok::semi); 2631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc, Alias, 26503bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson SS, IdentLoc, Ident); 266f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson} 267f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson 268c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal 269c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen. 270c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 271c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// linkage-specification: [C++ 7.5p2: dcl.link] 272c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 'extern' string-literal '{' declaration-seq[opt] '}' 273c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 'extern' string-literal declaration 274c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 2757d64271b162eaf5cae264ff64465b28af623dc17Chris LattnerDecl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) { 276c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor assert(Tok.is(tok::string_literal) && "Not a string literal!"); 277f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<8> LangBuffer; 278453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor bool Invalid = false; 2795f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid); 280453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor if (Invalid) 281d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 282c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 28399831e4677a7e2e051af636221694d60ba31fcdbRichard Smith // FIXME: This is incorrect: linkage-specifiers are parsed in translation 28499831e4677a7e2e051af636221694d60ba31fcdbRichard Smith // phase 7, so string-literal concatenation is supposed to occur. 28599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith // extern "" "C" "" "+" "+" { } is legal. 28699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith if (Tok.hasUDSuffix()) 28799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith Diag(Tok, diag::err_invalid_string_udl); 288c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner SourceLocation Loc = ConsumeStringToken(); 289c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 290074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor ParseScope LinkageScope(this, Scope::DeclScope); 291d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl *LinkageSpec 29223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnStartLinkageSpecification(getCurScope(), 293a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara DS.getSourceRange().getBegin(), 294d56638180014e60538cd666cd11fde6d4698e051Benjamin Kramer Loc, Lang, 295a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara Tok.is(tok::l_brace) ? Tok.getLocation() 296074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor : SourceLocation()); 297074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor 2980b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributesWithRange attrs(AttrFactory); 2994e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith MaybeParseCXX11Attributes(attrs); 3007f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseMicrosoftAttributes(attrs); 301193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 302074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor if (Tok.isNot(tok::l_brace)) { 303f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara // Reset the source range in DS, as the leading "extern" 304f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara // does not really belong to the inner declaration ... 305f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara DS.SetRangeStart(SourceLocation()); 306f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara DS.SetRangeEnd(SourceLocation()); 307f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara // ... but anyway remember that such an "extern" was seen. 30835f9a196ef897b9559de25aaecd957208f0b4f59Abramo Bagnara DS.setExternInLinkageSpec(true); 3097f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseExternalDeclaration(attrs, &DS); 31023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec, 311074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor SourceLocation()); 3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 313f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor 31463a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor DS.abort(); 31563a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor 3167f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ProhibitAttributes(attrs); 317bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 3184a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_brace); 3194a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 320f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 3210b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributesWithRange attrs(AttrFactory); 3224e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith MaybeParseCXX11Attributes(attrs); 3237f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseMicrosoftAttributes(attrs); 3247f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseExternalDeclaration(attrs); 325f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor } 326c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 3274a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 3287d64271b162eaf5cae264ff64465b28af623dc17Chris Lattner return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec, 3294a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 330c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner} 331e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 332f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or 333f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'. 334d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context, 33578b810559d89e996e00684335407443936ce34a1John McCall const ParsedTemplateInfo &TemplateInfo, 33678b810559d89e996e00684335407443936ce34a1John McCall SourceLocation &DeclEnd, 337c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith ParsedAttributesWithRange &attrs, 338c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith Decl **OwnedType) { 339f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(Tok.is(tok::kw_using) && "Not using token"); 3409735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian ObjCDeclContextSwitch ObjCDC(*this); 3419735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian 342f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Eat 'using'. 343f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation UsingLoc = ConsumeToken(); 344f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 34549f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor if (Tok.is(tok::code_completion)) { 34623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteUsing(getCurScope()); 3477d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 3487d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return 0; 34949f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor } 350193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 35178b810559d89e996e00684335407443936ce34a1John McCall // 'using namespace' means this is a using-directive. 35278b810559d89e996e00684335407443936ce34a1John McCall if (Tok.is(tok::kw_namespace)) { 35378b810559d89e996e00684335407443936ce34a1John McCall // Template parameters are always an error here. 35478b810559d89e996e00684335407443936ce34a1John McCall if (TemplateInfo.Kind) { 35578b810559d89e996e00684335407443936ce34a1John McCall SourceRange R = TemplateInfo.getSourceRange(); 35678b810559d89e996e00684335407443936ce34a1John McCall Diag(UsingLoc, diag::err_templated_using_directive) 35778b810559d89e996e00684335407443936ce34a1John McCall << R << FixItHint::CreateRemoval(R); 35878b810559d89e996e00684335407443936ce34a1John McCall } 35978b810559d89e996e00684335407443936ce34a1John McCall 3609735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs); 36178b810559d89e996e00684335407443936ce34a1John McCall } 362bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 363162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Otherwise, it must be a using-declaration or an alias-declaration. 36478b810559d89e996e00684335407443936ce34a1John McCall 36578b810559d89e996e00684335407443936ce34a1John McCall // Using declarations can't have attributes. 3667f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ProhibitAttributes(attrs); 3672f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner 3689735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd, 369a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian AS_none, OwnedType); 370f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 371f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 372f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes 373f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed. 374f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 375f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive: [C++ 7.3.p4: namespace.udir] 376f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'namespace' ::[opt] nested-name-specifier[opt] 377f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// namespace-name ; 378f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive: 379f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'namespace' ::[opt] nested-name-specifier[opt] 380f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// namespace-name attributes[opt] ; 381f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 382d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirective(unsigned Context, 38378b810559d89e996e00684335407443936ce34a1John McCall SourceLocation UsingLoc, 38478b810559d89e996e00684335407443936ce34a1John McCall SourceLocation &DeclEnd, 3857f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParsedAttributes &attrs) { 386f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token"); 387f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 388f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Eat 'namespace'. 389f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation NamespcLoc = ConsumeToken(); 390f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 39149f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor if (Tok.is(tok::code_completion)) { 39223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteUsingDirective(getCurScope()); 3937d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 3947d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return 0; 39549f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor } 396193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 397f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor CXXScopeSpec SS; 398f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Parse (optional) nested-name-specifier. 399efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 400f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 401f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor IdentifierInfo *NamespcName = 0; 402f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation IdentLoc = SourceLocation(); 403f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 404f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Parse namespace-name. 405823c44e6d73141f642e207980b4021ddcf09897bChris Lattner if (SS.isInvalid() || Tok.isNot(tok::identifier)) { 406f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor Diag(Tok, diag::err_expected_namespace_name); 407f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // If there was invalid namespace name, skip to end of decl, and eat ';'. 408f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SkipUntil(tok::semi); 409f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // FIXME: Are there cases, when we would like to call ActOnUsingDirective? 410d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 411f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor } 4121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 413823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Parse identifier. 414823c44e6d73141f642e207980b4021ddcf09897bChris Lattner NamespcName = Tok.getIdentifierInfo(); 415823c44e6d73141f642e207980b4021ddcf09897bChris Lattner IdentLoc = ConsumeToken(); 4161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 417823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Parse (optional) attributes (most likely GNU strong-using extension). 418bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt bool GNUAttr = false; 419bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.is(tok::kw___attribute)) { 420bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt GNUAttr = true; 4217f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseGNUAttributes(attrs); 422bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 4231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 424823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Eat ';'. 42597144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner DeclEnd = Tok.getLocation(); 4266869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner ExpectAndConsume(tok::semi, 4279ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor GNUAttr ? diag::err_expected_semi_after_attribute_list 4289ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor : diag::err_expected_semi_after_namespace_name, 4299ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor "", tok::semi); 430f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 43123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS, 4327f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall IdentLoc, NamespcName, attrs.getList()); 433f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 434f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 435162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration. 436162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// Assumes that 'using' was already seen. 437f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 438f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-declaration: [C++ 7.3.p3: namespace.udecl] 439f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'typename'[opt] ::[opt] nested-name-specifier 4409cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor/// unqualified-id 4419cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor/// 'using' :: unqualified-id 442f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 443d03de6aaa312d57dcd6e2bc76bed1e89f5c5019dRichard Smith/// alias-declaration: C++11 [dcl.dcl]p1 444d03de6aaa312d57dcd6e2bc76bed1e89f5c5019dRichard Smith/// 'using' identifier attribute-specifier-seq[opt] = type-id ; 445162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// 446d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDeclaration(unsigned Context, 44778b810559d89e996e00684335407443936ce34a1John McCall const ParsedTemplateInfo &TemplateInfo, 44878b810559d89e996e00684335407443936ce34a1John McCall SourceLocation UsingLoc, 44978b810559d89e996e00684335407443936ce34a1John McCall SourceLocation &DeclEnd, 450c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith AccessSpecifier AS, 451c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith Decl **OwnedType) { 4529cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor CXXScopeSpec SS; 4537ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall SourceLocation TypenameLoc; 4546b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith bool IsTypeName = false; 4556b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith ParsedAttributesWithRange Attrs(AttrFactory); 4562edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 4572edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt // FIXME: Simply skip the attributes and diagnose, don't bother parsing them. 4586b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith MaybeParseCXX11Attributes(Attrs); 4596b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith ProhibitAttributes(Attrs); 4606b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith Attrs.clear(); 4616b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith Attrs.Range = SourceRange(); 4629cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 4639cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Ignore optional 'typename'. 46412c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor // FIXME: This is wrong; we should parse this as a typename-specifier. 4659cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (Tok.is(tok::kw_typename)) { 4666b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith TypenameLoc = ConsumeToken(); 4679cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor IsTypeName = true; 4689cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 4699cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 4709cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Parse nested-name-specifier. 471efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 4729cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 4739cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Check nested-name specifier. 4749cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (SS.isInvalid()) { 4759cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SkipUntil(tok::semi); 476d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 4779cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 4781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 479193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // Parse the unqualified-id. We allow parsing of both constructor and 48012c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor // destructor names and allow the action module to diagnose any semantic 48112c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor // errors. 482e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara SourceLocation TemplateKWLoc; 48312c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor UnqualifiedId Name; 484193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam if (ParseUnqualifiedId(SS, 48512c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor /*EnteringContext=*/false, 48612c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor /*AllowDestructorName=*/true, 487193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam /*AllowConstructorName=*/true, 488b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType(), 489e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara TemplateKWLoc, 49012c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor Name)) { 4919cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SkipUntil(tok::semi); 492d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 4939cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 494193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 4956b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith MaybeParseCXX11Attributes(Attrs); 496162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 497162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Maybe this is an alias-declaration. 498162e1c1b487352434552147967c3dd296ebee2f7Richard Smith bool IsAliasDecl = Tok.is(tok::equal); 499162e1c1b487352434552147967c3dd296ebee2f7Richard Smith TypeResult TypeAlias; 500162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (IsAliasDecl) { 5016b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith // TODO: Can GNU attributes appear here? 502162e1c1b487352434552147967c3dd296ebee2f7Richard Smith ConsumeToken(); 503162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 50480ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith Diag(Tok.getLocation(), getLangOpts().CPlusPlus11 ? 5057fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_alias_declaration : 5067fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::ext_alias_declaration); 507162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 5083e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // Type alias templates cannot be specialized. 5093e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith int SpecKind = -1; 510536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith if (TemplateInfo.Kind == ParsedTemplateInfo::Template && 511536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith Name.getKind() == UnqualifiedId::IK_TemplateId) 5123e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SpecKind = 0; 5133e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization) 5143e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SpecKind = 1; 5153e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) 5163e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SpecKind = 2; 5173e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (SpecKind != -1) { 5183e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SourceRange Range; 5193e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (SpecKind == 0) 5203e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Range = SourceRange(Name.TemplateId->LAngleLoc, 5213e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Name.TemplateId->RAngleLoc); 5223e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith else 5233e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Range = TemplateInfo.getSourceRange(); 5243e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Diag(Range.getBegin(), diag::err_alias_declaration_specialization) 5253e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith << SpecKind << Range; 5263e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SkipUntil(tok::semi); 5273e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return 0; 5283e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 5293e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith 530162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Name must be an identifier. 531162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (Name.getKind() != UnqualifiedId::IK_Identifier) { 532162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Diag(Name.StartLocation, diag::err_alias_declaration_not_identifier); 533162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // No removal fixit: can't recover from this. 534162e1c1b487352434552147967c3dd296ebee2f7Richard Smith SkipUntil(tok::semi); 535162e1c1b487352434552147967c3dd296ebee2f7Richard Smith return 0; 536162e1c1b487352434552147967c3dd296ebee2f7Richard Smith } else if (IsTypeName) 537162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Diag(TypenameLoc, diag::err_alias_declaration_not_identifier) 538162e1c1b487352434552147967c3dd296ebee2f7Richard Smith << FixItHint::CreateRemoval(SourceRange(TypenameLoc, 539162e1c1b487352434552147967c3dd296ebee2f7Richard Smith SS.isNotEmpty() ? SS.getEndLoc() : TypenameLoc)); 540162e1c1b487352434552147967c3dd296ebee2f7Richard Smith else if (SS.isNotEmpty()) 541162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier) 542162e1c1b487352434552147967c3dd296ebee2f7Richard Smith << FixItHint::CreateRemoval(SS.getRange()); 543162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 5443e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TypeAlias = ParseTypeName(0, TemplateInfo.Kind ? 5453e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Declarator::AliasTemplateContext : 5466b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith Declarator::AliasDeclContext, AS, OwnedType, 5476b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith &Attrs); 5482edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt } else { 5492edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt // C++11 attributes are not allowed on a using-declaration, but GNU ones 5502edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt // are. 5516b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith ProhibitAttributes(Attrs); 5522edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 553162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Parse (optional) attributes (most likely GNU strong-using extension). 5546b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith MaybeParseGNUAttributes(Attrs); 5552edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt } 5561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5579cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Eat ';'. 5589cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor DeclEnd = Tok.getLocation(); 5599cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor ExpectAndConsume(tok::semi, diag::err_expected_semi_after, 5606b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith !Attrs.empty() ? "attributes list" : 561162e1c1b487352434552147967c3dd296ebee2f7Richard Smith IsAliasDecl ? "alias declaration" : "using declaration", 56212c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor tok::semi); 5639cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 56478b810559d89e996e00684335407443936ce34a1John McCall // Diagnose an attempt to declare a templated using-declaration. 565d03de6aaa312d57dcd6e2bc76bed1e89f5c5019dRichard Smith // In C++11, alias-declarations can be templates: 566162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // template <...> using id = type; 5673e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (TemplateInfo.Kind && !IsAliasDecl) { 56878b810559d89e996e00684335407443936ce34a1John McCall SourceRange R = TemplateInfo.getSourceRange(); 56978b810559d89e996e00684335407443936ce34a1John McCall Diag(UsingLoc, diag::err_templated_using_declaration) 57078b810559d89e996e00684335407443936ce34a1John McCall << R << FixItHint::CreateRemoval(R); 57178b810559d89e996e00684335407443936ce34a1John McCall 57278b810559d89e996e00684335407443936ce34a1John McCall // Unfortunately, we have to bail out instead of recovering by 57378b810559d89e996e00684335407443936ce34a1John McCall // ignoring the parameters, just in case the nested name specifier 57478b810559d89e996e00684335407443936ce34a1John McCall // depends on the parameters. 57578b810559d89e996e00684335407443936ce34a1John McCall return 0; 57678b810559d89e996e00684335407443936ce34a1John McCall } 57778b810559d89e996e00684335407443936ce34a1John McCall 578480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor // "typename" keyword is allowed for identifiers only, 579480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor // because it may be a type definition. 580480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor if (IsTypeName && Name.getKind() != UnqualifiedId::IK_Identifier) { 581480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor Diag(Name.getSourceRange().getBegin(), diag::err_typename_identifiers_only) 582480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor << FixItHint::CreateRemoval(SourceRange(TypenameLoc)); 583480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor // Proceed parsing, but reset the IsTypeName flag. 584480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor IsTypeName = false; 585480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor } 586480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor 5873e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (IsAliasDecl) { 5883e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams; 5895354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer MultiTemplateParamsArg TemplateParamsArg( 5903e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TemplateParams ? TemplateParams->data() : 0, 5913e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TemplateParams ? TemplateParams->size() : 0); 5923e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg, 5936b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith UsingLoc, Name, Attrs.getList(), 5946b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith TypeAlias); 5953e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 596162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 5978113ecfa4e41e2c888b1794389dfe3bce6386493Ted Kremenek return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS, 5986b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith Name, Attrs.getList(), 5997f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall IsTypeName, TypenameLoc); 600f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 601f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 602ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer/// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration. 603511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// 604c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// [C++0x] static_assert-declaration: 605c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// static_assert ( constant-expression , string-literal ) ; 606c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// 607ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer/// [C11] static_assert-declaration: 608c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// _Static_assert ( constant-expression , string-literal ) ; 609511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// 610d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){ 611c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne assert((Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) && 612c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne "Not a static_assert declaration"); 613c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne 6144e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11) 615ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer Diag(Tok, diag::ext_c11_static_assert); 616841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith if (Tok.is(tok::kw_static_assert)) 617841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith Diag(Tok, diag::warn_cxx98_compat_static_assert); 618c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne 619511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson SourceLocation StaticAssertLoc = ConsumeToken(); 6201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6214a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 6224a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.consumeOpen()) { 623511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson Diag(Tok, diag::err_expected_lparen); 6243686c71ff92e4357a78993a16a27185f16ab6234Richard Smith SkipMalformedDecl(); 625d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 626511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 6271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 62860d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AssertExpr(ParseConstantExpression()); 629511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson if (AssertExpr.isInvalid()) { 6303686c71ff92e4357a78993a16a27185f16ab6234Richard Smith SkipMalformedDecl(); 631d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 632511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 6331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 634ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi)) 635d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 636ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson 6370cc323c6bed7206f9743a9775ec8d9cb90655f9cRichard Smith if (!isTokenStringLiteral()) { 63897f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs Diag(Tok, diag::err_expected_string_literal) 63997f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs << /*Source='static_assert'*/1; 6403686c71ff92e4357a78993a16a27185f16ab6234Richard Smith SkipMalformedDecl(); 641d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 642511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 6431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 64460d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AssertMessage(ParseStringLiteralExpression()); 64599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith if (AssertMessage.isInvalid()) { 6463686c71ff92e4357a78993a16a27185f16ab6234Richard Smith SkipMalformedDecl(); 647d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 64899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith } 649511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 6504a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 6511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 65297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner DeclEnd = Tok.getLocation(); 6539ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert); 654511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 6559ae2f076ca5ab1feb3ba95629099ec2319833701John McCall return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, 6569ae2f076ca5ab1feb3ba95629099ec2319833701John McCall AssertExpr.take(), 657a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara AssertMessage.take(), 6584a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 659511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson} 660511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 6616fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// ParseDecltypeSpecifier - Parse a C++0x decltype specifier. 6626fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 6636fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 'decltype' ( expression ) 6646fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 66542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid BlaikieSourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) { 66642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie assert((Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) 66742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie && "Not a decltype specifier"); 66842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 6696fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson 67042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie ExprResult Result; 67142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation StartLoc = Tok.getLocation(); 67242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation EndLoc; 6731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 67442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Tok.is(tok::annot_decltype)) { 67542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Result = getExprAnnotation(Tok); 67642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie EndLoc = Tok.getAnnotationEndLoc(); 67742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie ConsumeToken(); 67842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Result.isInvalid()) { 67942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 68042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return EndLoc; 68142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 68242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } else { 683c7b5543ad32a5c265c02e71b2a6f9856440ed13fRichard Smith if (Tok.getIdentifierInfo()->isStr("decltype")) 684c7b5543ad32a5c265c02e71b2a6f9856440ed13fRichard Smith Diag(Tok, diag::warn_cxx98_compat_decltype); 68539304fad1c8a7b7e64121e9ae544b18e460b682cRichard Smith 68642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie ConsumeToken(); 6871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 68842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie BalancedDelimiterTracker T(*this, tok::l_paren); 68942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (T.expectAndConsume(diag::err_expected_lparen_after, 69042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie "decltype", tok::r_paren)) { 69142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 69242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return T.getOpenLocation() == Tok.getLocation() ? 69342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie StartLoc : T.getOpenLocation(); 69442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 6951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 69642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // Parse the expression 69742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 69842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // C++0x [dcl.type.simple]p4: 69942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // The operand of the decltype specifier is an unevaluated operand. 70076f3f69db1416425070177243e9f390122c553e0Richard Smith EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, 70176f3f69db1416425070177243e9f390122c553e0Richard Smith 0, /*IsDecltype=*/true); 70242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Result = ParseExpression(); 70342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Result.isInvalid()) { 70442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 7051e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis if (SkipUntil(tok::r_paren, /*StopAtSemi=*/true, /*DontConsume=*/true)) { 7061e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis EndLoc = ConsumeParen(); 7071e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis } else { 708569cdc82c1a99fe1e950a1ddbe5ff82df0b13f3dRichard Smith if (PP.isBacktrackEnabled() && Tok.is(tok::semi)) { 7091e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis // Backtrack to get the location of the last token before the semi. 7101e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis PP.RevertCachedTokens(2); 7111e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis ConsumeToken(); // the semi. 7121e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis EndLoc = ConsumeAnyToken(); 7131e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis assert(Tok.is(tok::semi)); 7141e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis } else { 7151e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis EndLoc = Tok.getLocation(); 7161e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis } 7171e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis } 7181e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis return EndLoc; 71942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 72042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 72142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // Match the ')' 72242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie T.consumeClose(); 72342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (T.getCloseLocation().isInvalid()) { 72442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 72542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // FIXME: this should return the location of the last token 72642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // that was consumed (by "consumeClose()") 72742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return T.getCloseLocation(); 72842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 72942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 73076f3f69db1416425070177243e9f390122c553e0Richard Smith Result = Actions.ActOnDecltypeExpression(Result.take()); 73176f3f69db1416425070177243e9f390122c553e0Richard Smith if (Result.isInvalid()) { 73276f3f69db1416425070177243e9f390122c553e0Richard Smith DS.SetTypeSpecError(); 73376f3f69db1416425070177243e9f390122c553e0Richard Smith return T.getCloseLocation(); 73476f3f69db1416425070177243e9f390122c553e0Richard Smith } 73576f3f69db1416425070177243e9f390122c553e0Richard Smith 73642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie EndLoc = T.getCloseLocation(); 73742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 7386fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson 7396fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson const char *PrevSpec = 0; 740fec54013fcd0eb72642741584ca04c1bc292bef8John McCall unsigned DiagID; 7416fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson // Check for duplicate type specifiers (e.g. "int decltype(a)"). 7421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec, 74342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DiagID, Result.release())) { 744fec54013fcd0eb72642741584ca04c1bc292bef8John McCall Diag(StartLoc, DiagID) << PrevSpec; 74542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 74642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 74742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return EndLoc; 74842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie} 74942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 75042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikievoid Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec& DS, 75142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation StartLoc, 75242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation EndLoc) { 75342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // make sure we have a token we can turn into an annotation token 75442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (PP.isBacktrackEnabled()) 75542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie PP.RevertCachedTokens(1); 75642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie else 75742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie PP.EnterToken(Tok); 75842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 75942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Tok.setKind(tok::annot_decltype); 76042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie setExprAnnotation(Tok, DS.getTypeSpecType() == TST_decltype ? 76142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.getRepAsExpr() : ExprResult()); 76242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Tok.setAnnotationEndLoc(EndLoc); 76342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Tok.setLocation(StartLoc); 76442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie PP.AnnotateCachedTokens(Tok); 7656fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson} 7666fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson 767db5d44b775c60166074acd184ca9f1981c10c2a7Sean Huntvoid Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) { 768db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt assert(Tok.is(tok::kw___underlying_type) && 769db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt "Not an underlying type specifier"); 770db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 771db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt SourceLocation StartLoc = ConsumeToken(); 7724a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 7734a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen_after, 7744a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor "__underlying_type", tok::r_paren)) { 775db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt return; 776db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt } 777db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 778db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt TypeResult Result = ParseTypeName(); 779db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt if (Result.isInvalid()) { 780db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt SkipUntil(tok::r_paren); 781db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt return; 782db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt } 783db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 784db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt // Match the ')' 7854a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 7864a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.getCloseLocation().isInvalid()) 787db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt return; 788db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 789db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt const char *PrevSpec = 0; 790db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt unsigned DiagID; 791ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec, 792db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt DiagID, Result.release())) 793db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt Diag(StartLoc, DiagID) << PrevSpec; 794db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt} 795db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 79609048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// ParseBaseTypeSpecifier - Parse a C++ base-type-specifier which is either a 79709048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class name or decltype-specifier. Note that we only check that the result 79809048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// names a type; semantic analysis will need to verify that the type names a 79909048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class. The result is either a type or null, depending on whether a type 80009048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// name was found. 80142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// 802053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// base-type-specifier: [C++11 class.derived] 80309048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class-or-decltype 804053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// class-or-decltype: [C++11 class.derived] 80509048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// nested-name-specifier[opt] class-name 80609048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// decltype-specifier 807053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// class-name: [C++ class.name] 80842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// identifier 8097f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor/// simple-template-id 8101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 811053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// In C++98, instead of base-type-specifier, we have: 812053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// 813053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// ::[opt] nested-name-specifier[opt] class-name 81422216eb4fb0936d2488fc03abd285d135c36ff01David BlaikieParser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc, 81522216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie SourceLocation &EndLocation) { 8167fe3878a36750515fb9772414ecb2489cf149d19David Blaikie // Ignore attempts to use typename 8177fe3878a36750515fb9772414ecb2489cf149d19David Blaikie if (Tok.is(tok::kw_typename)) { 8187fe3878a36750515fb9772414ecb2489cf149d19David Blaikie Diag(Tok, diag::err_expected_class_name_not_template) 8197fe3878a36750515fb9772414ecb2489cf149d19David Blaikie << FixItHint::CreateRemoval(Tok.getLocation()); 8207fe3878a36750515fb9772414ecb2489cf149d19David Blaikie ConsumeToken(); 8217fe3878a36750515fb9772414ecb2489cf149d19David Blaikie } 8227fe3878a36750515fb9772414ecb2489cf149d19David Blaikie 823152aa4b87633754801598ee282e1a17c3ec49257David Blaikie // Parse optional nested-name-specifier 824152aa4b87633754801598ee282e1a17c3ec49257David Blaikie CXXScopeSpec SS; 825152aa4b87633754801598ee282e1a17c3ec49257David Blaikie ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 826152aa4b87633754801598ee282e1a17c3ec49257David Blaikie 827152aa4b87633754801598ee282e1a17c3ec49257David Blaikie BaseLoc = Tok.getLocation(); 828152aa4b87633754801598ee282e1a17c3ec49257David Blaikie 82922216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie // Parse decltype-specifier 83042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // tok == kw_decltype is just error recovery, it can only happen when SS 83142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // isn't empty 83242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) { 833152aa4b87633754801598ee282e1a17c3ec49257David Blaikie if (SS.isNotEmpty()) 834152aa4b87633754801598ee282e1a17c3ec49257David Blaikie Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype) 835152aa4b87633754801598ee282e1a17c3ec49257David Blaikie << FixItHint::CreateRemoval(SS.getRange()); 83622216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie // Fake up a Declarator to use with ActOnTypeName. 83722216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie DeclSpec DS(AttrFactory); 83822216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie 839b57775709666e50cd925f9fc589d0fd895fc79a6David Blaikie EndLocation = ParseDecltypeSpecifier(DS); 84022216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie 84122216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 84222216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 84322216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie } 84422216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie 8457f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor // Check whether we have a template-id that names a type. 8467f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor if (Tok.is(tok::annot_template_id)) { 84725a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 848d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor if (TemplateId->Kind == TNK_Type_template || 849d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor TemplateId->Kind == TNK_Dependent_template_name) { 850059101f922de6eb765601459925f4c8914420b23Douglas Gregor AnnotateTemplateIdTokenAsType(); 8517f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 8527f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); 853b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType Type = getTypeAnnotation(Tok); 8547f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor EndLocation = Tok.getAnnotationEndLoc(); 8557f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor ConsumeToken(); 85631a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor 85731a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor if (Type) 85831a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return Type; 85931a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return true; 8607f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor } 8617f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 8627f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor // Fall through to produce an error below. 8637f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor } 8647f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 86542a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor if (Tok.isNot(tok::identifier)) { 8661ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_class_name); 86731a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return true; 86842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor } 86942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 87084d0a19828599e8623223632d59447fd498999cfDouglas Gregor IdentifierInfo *Id = Tok.getIdentifierInfo(); 87184d0a19828599e8623223632d59447fd498999cfDouglas Gregor SourceLocation IdLoc = ConsumeToken(); 87284d0a19828599e8623223632d59447fd498999cfDouglas Gregor 87384d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (Tok.is(tok::less)) { 87484d0a19828599e8623223632d59447fd498999cfDouglas Gregor // It looks the user intended to write a template-id here, but the 87584d0a19828599e8623223632d59447fd498999cfDouglas Gregor // template-name was wrong. Try to fix that. 87684d0a19828599e8623223632d59447fd498999cfDouglas Gregor TemplateNameKind TNK = TNK_Type_template; 87784d0a19828599e8623223632d59447fd498999cfDouglas Gregor TemplateTy Template; 87823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(), 879059101f922de6eb765601459925f4c8914420b23Douglas Gregor &SS, Template, TNK)) { 88084d0a19828599e8623223632d59447fd498999cfDouglas Gregor Diag(IdLoc, diag::err_unknown_template_name) 88184d0a19828599e8623223632d59447fd498999cfDouglas Gregor << Id; 88284d0a19828599e8623223632d59447fd498999cfDouglas Gregor } 883193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 88484d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (!Template) 88584d0a19828599e8623223632d59447fd498999cfDouglas Gregor return true; 88684d0a19828599e8623223632d59447fd498999cfDouglas Gregor 887193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // Form the template name 88884d0a19828599e8623223632d59447fd498999cfDouglas Gregor UnqualifiedId TemplateName; 88984d0a19828599e8623223632d59447fd498999cfDouglas Gregor TemplateName.setIdentifier(Id, IdLoc); 890193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 89184d0a19828599e8623223632d59447fd498999cfDouglas Gregor // Parse the full template-id, then turn it into a type. 892e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), 893e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara TemplateName, true)) 89484d0a19828599e8623223632d59447fd498999cfDouglas Gregor return true; 89584d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (TNK == TNK_Dependent_template_name) 896059101f922de6eb765601459925f4c8914420b23Douglas Gregor AnnotateTemplateIdTokenAsType(); 897193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 89884d0a19828599e8623223632d59447fd498999cfDouglas Gregor // If we didn't end up with a typename token, there's nothing more we 89984d0a19828599e8623223632d59447fd498999cfDouglas Gregor // can do. 90084d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (Tok.isNot(tok::annot_typename)) 90184d0a19828599e8623223632d59447fd498999cfDouglas Gregor return true; 902193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 90384d0a19828599e8623223632d59447fd498999cfDouglas Gregor // Retrieve the type from the annotation token, consume that token, and 90484d0a19828599e8623223632d59447fd498999cfDouglas Gregor // return. 90584d0a19828599e8623223632d59447fd498999cfDouglas Gregor EndLocation = Tok.getAnnotationEndLoc(); 906b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType Type = getTypeAnnotation(Tok); 90784d0a19828599e8623223632d59447fd498999cfDouglas Gregor ConsumeToken(); 90884d0a19828599e8623223632d59447fd498999cfDouglas Gregor return Type; 90984d0a19828599e8623223632d59447fd498999cfDouglas Gregor } 91084d0a19828599e8623223632d59447fd498999cfDouglas Gregor 91142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // We have an identifier; check whether it is actually a type. 912c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain IdentifierInfo *CorrectedII = 0; 913059101f922de6eb765601459925f4c8914420b23Douglas Gregor ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true, 9149e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor false, ParsedType(), 915fad03b75e0297546c5d12ec420b5b79d5b7baa2aAbramo Bagnara /*IsCtorOrDtorName=*/false, 916c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain /*NonTrivialTypeSourceInfo=*/true, 917c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain &CorrectedII); 918193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam if (!Type) { 919124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor Diag(IdLoc, diag::err_expected_class_name); 92031a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return true; 92142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor } 92242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 92342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Consume the identifier. 92484d0a19828599e8623223632d59447fd498999cfDouglas Gregor EndLocation = IdLoc; 9255606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky 9265606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky // Fake up a Declarator to use with ActOnTypeName. 9270b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall DeclSpec DS(AttrFactory); 9285606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky DS.SetRangeStart(IdLoc); 9295606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky DS.SetRangeEnd(EndLocation); 930059101f922de6eb765601459925f4c8914420b23Douglas Gregor DS.getTypeSpecScope() = SS; 9315606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky 9325606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky const char *PrevSpec = 0; 9335606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky unsigned DiagID; 9345606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type); 9355606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky 9365606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 9375606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 93842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor} 93942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 940c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallvoid Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) { 941c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall while (Tok.is(tok::kw___single_inheritance) || 942c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall Tok.is(tok::kw___multiple_inheritance) || 943c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall Tok.is(tok::kw___virtual_inheritance)) { 944c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 945c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall SourceLocation AttrNameLoc = ConsumeToken(); 946c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 94793f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt SourceLocation(), 0, 0, AttributeList::AS_GNU); 948c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall } 949c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall} 950c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall 951c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// Determine whether the following tokens are valid after a type-specifier 952c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// which could be a standalone declaration. This will conservatively return 953c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// true if there's any doubt, and is appropriate for insert-';' fixits. 954139be7007eba3bd491ca50297888be507753a95dRichard Smithbool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) { 955c9f351700721150a985f21844fbfec55b04e861dRichard Smith // This switch enumerates the valid "follow" set for type-specifiers. 956c9f351700721150a985f21844fbfec55b04e861dRichard Smith switch (Tok.getKind()) { 957c9f351700721150a985f21844fbfec55b04e861dRichard Smith default: break; 958c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::semi: // struct foo {...} ; 959c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::star: // struct foo {...} * P; 960c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::amp: // struct foo {...} & R = ... 961ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith case tok::ampamp: // struct foo {...} && R = ... 962c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::identifier: // struct foo {...} V ; 963c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::r_paren: //(struct foo {...} ) {4} 964c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::annot_cxxscope: // struct foo {...} a:: b; 965c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::annot_typename: // struct foo {...} a ::b; 966c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::annot_template_id: // struct foo {...} a<int> ::b; 967c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::l_paren: // struct foo {...} ( x); 968c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::comma: // __builtin_offsetof(struct foo{...} , 969ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith case tok::kw_operator: // struct foo operator ++() {...} 970c9f351700721150a985f21844fbfec55b04e861dRichard Smith return true; 971139be7007eba3bd491ca50297888be507753a95dRichard Smith case tok::colon: 972139be7007eba3bd491ca50297888be507753a95dRichard Smith return CouldBeBitfield; // enum E { ... } : 2; 973c9f351700721150a985f21844fbfec55b04e861dRichard Smith // Type qualifiers 974c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_const: // struct foo {...} const x; 975c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_volatile: // struct foo {...} volatile x; 976c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_restrict: // struct foo {...} restrict x; 977ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith // Function specifiers 978ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith // Note, no 'explicit'. An explicit function must be either a conversion 979ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith // operator or a constructor. Either way, it can't have a return type. 980ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith case tok::kw_inline: // struct foo inline f(); 981ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith case tok::kw_virtual: // struct foo virtual f(); 982ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith case tok::kw_friend: // struct foo friend f(); 983c9f351700721150a985f21844fbfec55b04e861dRichard Smith // Storage-class specifiers 984c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_static: // struct foo {...} static x; 985c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_extern: // struct foo {...} extern x; 986c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_typedef: // struct foo {...} typedef x; 987c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_register: // struct foo {...} register x; 988c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_auto: // struct foo {...} auto x; 989c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_mutable: // struct foo {...} mutable x; 990ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith case tok::kw_thread_local: // struct foo {...} thread_local x; 991c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_constexpr: // struct foo {...} constexpr x; 992c9f351700721150a985f21844fbfec55b04e861dRichard Smith // As shown above, type qualifiers and storage class specifiers absolutely 993c9f351700721150a985f21844fbfec55b04e861dRichard Smith // can occur after class specifiers according to the grammar. However, 994c9f351700721150a985f21844fbfec55b04e861dRichard Smith // almost no one actually writes code like this. If we see one of these, 995c9f351700721150a985f21844fbfec55b04e861dRichard Smith // it is much more likely that someone missed a semi colon and the 996c9f351700721150a985f21844fbfec55b04e861dRichard Smith // type/storage class specifier we're seeing is part of the *next* 997c9f351700721150a985f21844fbfec55b04e861dRichard Smith // intended declaration, as in: 998c9f351700721150a985f21844fbfec55b04e861dRichard Smith // 999c9f351700721150a985f21844fbfec55b04e861dRichard Smith // struct foo { ... } 1000c9f351700721150a985f21844fbfec55b04e861dRichard Smith // typedef int X; 1001c9f351700721150a985f21844fbfec55b04e861dRichard Smith // 1002c9f351700721150a985f21844fbfec55b04e861dRichard Smith // We'd really like to emit a missing semicolon error instead of emitting 1003c9f351700721150a985f21844fbfec55b04e861dRichard Smith // an error on the 'int' saying that you can't have two type specifiers in 1004c9f351700721150a985f21844fbfec55b04e861dRichard Smith // the same declaration of X. Because of this, we look ahead past this 1005c9f351700721150a985f21844fbfec55b04e861dRichard Smith // token to see if it's a type specifier. If so, we know the code is 1006c9f351700721150a985f21844fbfec55b04e861dRichard Smith // otherwise invalid, so we can produce the expected semi error. 1007c9f351700721150a985f21844fbfec55b04e861dRichard Smith if (!isKnownToBeTypeSpecifier(NextToken())) 1008c9f351700721150a985f21844fbfec55b04e861dRichard Smith return true; 1009c9f351700721150a985f21844fbfec55b04e861dRichard Smith break; 1010c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::r_brace: // struct bar { struct foo {...} } 1011c9f351700721150a985f21844fbfec55b04e861dRichard Smith // Missing ';' at end of struct is accepted as an extension in C mode. 1012c9f351700721150a985f21844fbfec55b04e861dRichard Smith if (!getLangOpts().CPlusPlus) 1013c9f351700721150a985f21844fbfec55b04e861dRichard Smith return true; 1014c9f351700721150a985f21844fbfec55b04e861dRichard Smith break; 1015ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith // C++11 attributes 1016ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith case tok::l_square: // enum E [[]] x 1017ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith // Note, no tok::kw_alignas here; alignas cannot appertain to a type. 1018ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith return getLangOpts().CPlusPlus11 && NextToken().is(tok::l_square); 10198338a9d28c4a9d06b19b1c5df51e70182914e2dfRichard Smith case tok::greater: 10208338a9d28c4a9d06b19b1c5df51e70182914e2dfRichard Smith // template<class T = class X> 10218338a9d28c4a9d06b19b1c5df51e70182914e2dfRichard Smith return getLangOpts().CPlusPlus; 1022c9f351700721150a985f21844fbfec55b04e861dRichard Smith } 1023c9f351700721150a985f21844fbfec55b04e861dRichard Smith return false; 1024c9f351700721150a985f21844fbfec55b04e861dRichard Smith} 1025c9f351700721150a985f21844fbfec55b04e861dRichard Smith 1026e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or 1027e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which 1028e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that 102969730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith/// cannot start a definition. 1030e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1031e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-specifier: [C++ class] 1032e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head '{' member-specification[opt] '}' 1033e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head '{' member-specification[opt] '}' attributes[opt] 1034e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head: 1035e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key identifier[opt] base-clause[opt] 1036e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key nested-name-specifier identifier base-clause[opt] 1037e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key nested-name-specifier[opt] simple-template-id 1038e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-clause[opt] 1039e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] class-key attributes[opt] identifier[opt] base-clause[opt] 10401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU] class-key attributes[opt] nested-name-specifier 1041e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// identifier base-clause[opt] 10421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU] class-key attributes[opt] nested-name-specifier[opt] 1043e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// simple-template-id base-clause[opt] 1044e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key: 1045e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'class' 1046e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'struct' 1047e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'union' 1048e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1049e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier: [C++ dcl.type.elab] 10501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// class-key ::[opt] nested-name-specifier[opt] identifier 10511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// class-key ::[opt] nested-name-specifier[opt] 'template'[opt] 10521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// simple-template-id 1053e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1054e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// Note that the C++ class-specifier and elaborated-type-specifier, 1055e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// together, subsume the C99 struct-or-union-specifier: 1056e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1057e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union-specifier: [C99 6.7.2.1] 1058e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union identifier[opt] '{' struct-contents '}' 1059e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union identifier 1060e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] struct-or-union attributes[opt] identifier[opt] '{' struct-contents 1061e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// '}' attributes[opt] 1062e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] struct-or-union attributes[opt] identifier 1063e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union: 1064e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'struct' 1065e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'union' 10664c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattnervoid Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, 10674c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner SourceLocation StartLoc, DeclSpec &DS, 10684d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor const ParsedTemplateInfo &TemplateInfo, 1069efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor AccessSpecifier AS, 10702e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han bool EnteringContext, DeclSpecContext DSC, 1071ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling ParsedAttributesWithRange &Attributes) { 107217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos DeclSpec::TST TagType; 107317d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos if (TagTokKind == tok::kw_struct) 107417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType = DeclSpec::TST_struct; 107517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos else if (TagTokKind == tok::kw___interface) 107617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType = DeclSpec::TST_interface; 107717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos else if (TagTokKind == tok::kw_class) 107817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType = DeclSpec::TST_class; 107917d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos else { 10804c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner assert(TagTokKind == tok::kw_union && "Not a class specifier"); 10814c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner TagType = DeclSpec::TST_union; 10824c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner } 1083e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1084374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor if (Tok.is(tok::code_completion)) { 1085374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor // Code completion for a struct, class, or union name. 108623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteTag(getCurScope(), TagType); 10877d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return cutOffParsing(); 1088374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor } 1089193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 1090926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // C++03 [temp.explicit] 14.7.2/8: 1091926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // The usual access checking rules do not apply to names used to specify 1092926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // explicit instantiations. 1093926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // 1094926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // As an extension we do not perform access checking on the names used to 1095926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // specify explicit specializations either. This is important to allow 1096926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // specializing traits classes for private types. 109713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // 109813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // Note that we don't suppress if this turns out to be an elaborated 109913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // type specifier. 110013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall bool shouldDelayDiagsInTag = 110113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation || 110213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization); 110313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag); 1104926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth 11052edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ParsedAttributesWithRange attrs(AttrFactory); 1106e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If attributes exist after tag, parse them. 1107e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw___attribute)) 11087f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseGNUAttributes(attrs); 1109e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1110f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff // If declspecs exist after tag, parse them. 1111b1d397c23e1f8fd8b404d5731d531e7500f7140dJohn McCall while (Tok.is(tok::kw___declspec)) 11127f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseMicrosoftDeclSpec(attrs); 1113193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 1114c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall // Parse inheritance specifiers. 1115c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall if (Tok.is(tok::kw___single_inheritance) || 1116c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall Tok.is(tok::kw___multiple_inheritance) || 1117c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall Tok.is(tok::kw___virtual_inheritance)) 1118c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ParseMicrosoftInheritanceClassAttributes(attrs); 1119c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall 1120bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // If C++0x attributes exist here, parse them. 1121bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Are we consistent with the ordering of parsing of different 1122bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // styles of attributes? 11234e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith MaybeParseCXX11Attributes(attrs); 11241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 112507fc1ba7553f2f5bf26984091197311decd9028eMichael Han // Source location used by FIXIT to insert misplaced 112607fc1ba7553f2f5bf26984091197311decd9028eMichael Han // C++11 attributes 112707fc1ba7553f2f5bf26984091197311decd9028eMichael Han SourceLocation AttrFixitLoc = Tok.getLocation(); 112807fc1ba7553f2f5bf26984091197311decd9028eMichael Han 112920c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley if (TagType == DeclSpec::TST_struct && 1130b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor !Tok.is(tok::identifier) && 1131b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.getIdentifierInfo() && 1132b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor (Tok.is(tok::kw___is_arithmetic) || 1133b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_convertible) || 113420c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley Tok.is(tok::kw___is_empty) || 1135b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_floating_point) || 1136b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_function) || 113720c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley Tok.is(tok::kw___is_fundamental) || 1138b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_integral) || 1139b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_member_function_pointer) || 1140b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_member_pointer) || 1141b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_pod) || 1142b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_pointer) || 1143b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_same) || 1144877222e2491bbc40a5c74cc100c540983f306b70Douglas Gregor Tok.is(tok::kw___is_scalar) || 1145b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_signed) || 1146b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_unsigned) || 1147b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_void))) { 1148688761409155b47c39eb5dae1b8c6c8a9f43307aDouglas Gregor // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the 1149b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // name of struct templates, but some are keywords in GCC >= 4.3 1150b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // and Clang. Therefore, when we see the token sequence "struct 1151b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // X", make X into a normal identifier rather than a keyword, to 1152b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // allow libstdc++ 4.2 and libc++ to work properly. 1153646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis Tok.getIdentifierInfo()->RevertTokenIDToIdentifier(); 1154b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor Tok.setKind(tok::identifier); 1155b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor } 11561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1157eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Parse the (optional) nested-name-specifier. 1158aa87d33309f505b68c3bfc17486c93e4d224b24fJohn McCall CXXScopeSpec &SS = DS.getTypeSpecScope(); 11594e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus) { 116008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner // "FOO : BAR" is not a potential typo for "FOO::BAR". 116108d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner ColonProtectionRAIIObject X(*this); 1162193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 1163efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext)) 1164207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall DS.SetTypeSpecError(); 11659ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall if (SS.isSet()) 116608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) 116708d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner Diag(Tok, diag::err_expected_ident); 116808d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner } 1169cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor 11702cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams; 11712cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor 1172cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor // Parse the (optional) class name or simple-template-id. 1173e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IdentifierInfo *Name = 0; 1174e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation NameLoc; 117539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateIdAnnotation *TemplateId = 0; 1176e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::identifier)) { 1177e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Name = Tok.getIdentifierInfo(); 1178e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor NameLoc = ConsumeToken(); 1179193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 11804e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Tok.is(tok::less) && getLangOpts().CPlusPlus) { 1181193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // The name was supposed to refer to a template, but didn't. 11822cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // Eat the template argument list and try to continue parsing this as 11832cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // a class (or template thereof). 11842cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor TemplateArgList TemplateArgs; 11852cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor SourceLocation LAngleLoc, RAngleLoc; 1186059101f922de6eb765601459925f4c8914420b23Douglas Gregor if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, SS, 11872cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor true, LAngleLoc, 1188314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor TemplateArgs, RAngleLoc)) { 11892cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // We couldn't parse the template argument list at all, so don't 11902cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // try to give any location information for the list. 11912cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor LAngleLoc = RAngleLoc = SourceLocation(); 11922cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor } 1193193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 11942cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor Diag(NameLoc, diag::err_explicit_spec_non_template) 119517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) 119617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos << (TagType == DeclSpec::TST_class? 0 119717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos : TagType == DeclSpec::TST_struct? 1 119817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos : TagType == DeclSpec::TST_interface? 2 119917d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos : 3) 120017d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos << Name 120117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos << SourceRange(LAngleLoc, RAngleLoc); 120217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos 1203193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // Strip off the last template parameter list if it was empty, since 1204c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor // we've removed its template argument list. 1205c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) { 1206c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor if (TemplateParams && TemplateParams->size() > 1) { 1207c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor TemplateParams->pop_back(); 1208c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor } else { 1209c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor TemplateParams = 0; 1210193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind 1211c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor = ParsedTemplateInfo::NonTemplate; 1212c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor } 1213c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor } else if (TemplateInfo.Kind 1214c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor == ParsedTemplateInfo::ExplicitInstantiation) { 1215c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor // Pretend this is just a forward declaration. 12162cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor TemplateParams = 0; 1217193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind 12182cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor = ParsedTemplateInfo::NonTemplate; 1219193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc 1220c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor = SourceLocation(); 1221c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc 1222c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor = SourceLocation(); 12232cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor } 12242cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor } 122539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor } else if (Tok.is(tok::annot_template_id)) { 122625a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateId = takeTemplateIdAnnotation(Tok); 122739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor NameLoc = ConsumeToken(); 1228cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor 1229059101f922de6eb765601459925f4c8914420b23Douglas Gregor if (TemplateId->Kind != TNK_Type_template && 1230059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->Kind != TNK_Dependent_template_name) { 123139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // The template-name in the simple-template-id refers to 123239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // something other than a class template. Give an appropriate 123339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // error message and skip to the ';'. 123439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor SourceRange Range(NameLoc); 123539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (SS.isNotEmpty()) 123639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor Range.setBegin(SS.getBeginLoc()); 123739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor 123839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template) 123939a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor << Name << static_cast<int>(TemplateId->Kind) << Range; 12401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 124139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor DS.SetTypeSpecError(); 124239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor SkipUntil(tok::semi, false, true); 124339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor return; 1244cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor } 1245e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1246e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 12477796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // There are four options here. 12487796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - If we are in a trailing return type, this is always just a reference, 12497796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // and we must not try to parse a definition. For instance, 12507796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // [] () -> struct S { }; 12517796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // does not define a type. 12527796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - If we have 'struct foo {...', 'struct foo :...', 12537796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // 'struct foo final :' or 'struct foo final {', then this is a definition. 12547796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - If we have 'struct foo;', then this is either a forward declaration 12557796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // or a friend declaration, which have to be treated differently. 12567796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - Otherwise we have something like 'struct foo xyz', a reference. 12572e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // 12582e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // We also detect these erroneous cases to provide better diagnostic for 12592e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // C++11 attributes parsing. 12602e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // - attributes follow class name: 12612e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // struct foo [[]] {}; 12622e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // - attributes appear before or after 'final': 12632e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // struct foo [[]] final [[]] {}; 12642e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // 126569730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // However, in type-specifier-seq's, things look like declarations but are 126669730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // just references, e.g. 126769730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // new struct s; 1268d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl // or 126969730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // &T::operator struct s; 127069730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // For these, DSC is DSC_type_specifier. 12712e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 12722e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // If there are attributes after class name, parse them. 12734e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith MaybeParseCXX11Attributes(Attributes); 12742e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 1275f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall Sema::TagUseKind TUK; 12767796eb5643244f3134834253ce5ea89107ac21c1Richard Smith if (DSC == DSC_trailing) 12777796eb5643244f3134834253ce5ea89107ac21c1Richard Smith TUK = Sema::TUK_Reference; 12787796eb5643244f3134834253ce5ea89107ac21c1Richard Smith else if (Tok.is(tok::l_brace) || 12797796eb5643244f3134834253ce5ea89107ac21c1Richard Smith (getLangOpts().CPlusPlus && Tok.is(tok::colon)) || 12804e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith (isCXX11FinalKeyword() && 12816f42669b7c0b81b07a15a0483aa5e897ce57cb45David Blaikie (NextToken().is(tok::l_brace) || NextToken().is(tok::colon)))) { 1282d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor if (DS.isFriendSpecified()) { 1283d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // C++ [class.friend]p2: 1284d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // A class shall not be defined in a friend declaration. 1285bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith Diag(Tok.getLocation(), diag::err_friend_decl_defines_type) 1286d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor << SourceRange(DS.getFriendSpecLoc()); 1287d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor 1288d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // Skip everything up to the semicolon, so that this looks like a proper 1289d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // friend class (or template thereof) declaration. 1290d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor SkipUntil(tok::semi, true, true); 1291f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = Sema::TUK_Friend; 1292d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor } else { 1293d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // Okay, this is a class definition. 1294f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = Sema::TUK_Definition; 1295d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor } 1296150d853343758281f7b0c44e058ea81da45b79beRichard Smith } else if (isCXX11FinalKeyword() && (NextToken().is(tok::l_square) || 1297150d853343758281f7b0c44e058ea81da45b79beRichard Smith NextToken().is(tok::kw_alignas))) { 12982e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // We can't tell if this is a definition or reference 12992e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // until we skipped the 'final' and C++11 attribute specifiers. 13002e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han TentativeParsingAction PA(*this); 13012e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 13022e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // Skip the 'final' keyword. 13032e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han ConsumeToken(); 13042e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 13052e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // Skip C++11 attribute specifiers. 13062e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han while (true) { 13072e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) { 13082e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han ConsumeBracket(); 13092e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han if (!SkipUntil(tok::r_square)) 13102e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han break; 1311150d853343758281f7b0c44e058ea81da45b79beRichard Smith } else if (Tok.is(tok::kw_alignas) && NextToken().is(tok::l_paren)) { 13122e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han ConsumeToken(); 13132e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han ConsumeParen(); 13142e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han if (!SkipUntil(tok::r_paren)) 13152e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han break; 13162e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han } else { 13172e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han break; 13182e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han } 13192e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han } 13202e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 13212e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han if (Tok.is(tok::l_brace) || Tok.is(tok::colon)) 13222e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han TUK = Sema::TUK_Definition; 13232e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han else 13242e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han TUK = Sema::TUK_Reference; 13252e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 13262e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han PA.Revert(); 1327c9f351700721150a985f21844fbfec55b04e861dRichard Smith } else if (DSC != DSC_type_specifier && 1328c9f351700721150a985f21844fbfec55b04e861dRichard Smith (Tok.is(tok::semi) || 1329139be7007eba3bd491ca50297888be507753a95dRichard Smith (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) { 1330f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration; 133117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos if (Tok.isNot(tok::semi)) { 133217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos // A semicolon was missing after this declaration. Diagnose and recover. 133317d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, 133417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos DeclSpec::getSpecifierName(TagType)); 133517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos PP.EnterToken(Tok); 133617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos Tok.setKind(tok::semi); 133717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos } 1338c9f351700721150a985f21844fbfec55b04e861dRichard Smith } else 1339f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = Sema::TUK_Reference; 1340e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 13412e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // Forbid misplaced attributes. In cases of a reference, we pass attributes 13422e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // to caller to handle. 134307fc1ba7553f2f5bf26984091197311decd9028eMichael Han if (TUK != Sema::TUK_Reference) { 134407fc1ba7553f2f5bf26984091197311decd9028eMichael Han // If this is not a reference, then the only possible 134507fc1ba7553f2f5bf26984091197311decd9028eMichael Han // valid place for C++11 attributes to appear here 134607fc1ba7553f2f5bf26984091197311decd9028eMichael Han // is between class-key and class-name. If there are 134707fc1ba7553f2f5bf26984091197311decd9028eMichael Han // any attributes after class-name, we try a fixit to move 134807fc1ba7553f2f5bf26984091197311decd9028eMichael Han // them to the right place. 134907fc1ba7553f2f5bf26984091197311decd9028eMichael Han SourceRange AttrRange = Attributes.Range; 135007fc1ba7553f2f5bf26984091197311decd9028eMichael Han if (AttrRange.isValid()) { 135107fc1ba7553f2f5bf26984091197311decd9028eMichael Han Diag(AttrRange.getBegin(), diag::err_attributes_not_allowed) 135207fc1ba7553f2f5bf26984091197311decd9028eMichael Han << AttrRange 135307fc1ba7553f2f5bf26984091197311decd9028eMichael Han << FixItHint::CreateInsertionFromRange(AttrFixitLoc, 135407fc1ba7553f2f5bf26984091197311decd9028eMichael Han CharSourceRange(AttrRange, true)) 135507fc1ba7553f2f5bf26984091197311decd9028eMichael Han << FixItHint::CreateRemoval(AttrRange); 135607fc1ba7553f2f5bf26984091197311decd9028eMichael Han 135707fc1ba7553f2f5bf26984091197311decd9028eMichael Han // Recover by adding misplaced attributes to the attribute list 135807fc1ba7553f2f5bf26984091197311decd9028eMichael Han // of the class so they can be applied on the class later. 135907fc1ba7553f2f5bf26984091197311decd9028eMichael Han attrs.takeAllFrom(Attributes); 136007fc1ba7553f2f5bf26984091197311decd9028eMichael Han } 136107fc1ba7553f2f5bf26984091197311decd9028eMichael Han } 13622e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 136313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // If this is an elaborated type specifier, and we delayed 136413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // diagnostics before, just merge them into the current pool. 136513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall if (shouldDelayDiagsInTag) { 136613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall diagsFromTag.done(); 136713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall if (TUK == Sema::TUK_Reference) 136813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall diagsFromTag.redelay(); 136913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall } 137013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall 1371207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error || 1372f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK != Sema::TUK_Definition)) { 1373207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall if (DS.getTypeSpecType() != DeclSpec::TST_error) { 1374207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall // We have a declaration or reference to an anonymous class. 1375207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall Diag(StartLoc, diag::err_anon_type_definition) 1376207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall << DeclSpec::getSpecifierName(TagType); 1377207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall } 1378e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1379e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SkipUntil(tok::comma, true); 1380e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor return; 1381e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1382e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1383ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor // Create the tag portion of the class or class template. 1384d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall DeclResult TagOrTempResult = true; // invalid 1385d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall TypeResult TypeResult = true; // invalid 13864d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 1387402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor bool Owned = false; 1388f1bbbb49f06a7462476cd88166fccda5feb15cabJohn McCall if (TemplateId) { 13894d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // Explicit specialization, class template partial specialization, 13904d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // or explicit instantiation. 13915354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), 139239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->NumArgs); 13934d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && 1394f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK == Sema::TUK_Declaration) { 13954d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // This is an explicit instantiation of a class template. 13962edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 13972edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 13984d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TagOrTempResult 139923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnExplicitInstantiation(getCurScope(), 140045f965581935791a018df829a14dff53c1dd8f47Douglas Gregor TemplateInfo.ExternLoc, 14011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateInfo.TemplateLoc, 14024d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TagType, 14031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump StartLoc, 14044d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor SS, 14052b5289b6fd7e3d9899868410a498c081c9595662John McCall TemplateId->Template, 14061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->TemplateNameLoc, 14071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->LAngleLoc, 14084d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TemplateArgsPtr, 14091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->RAngleLoc, 14107f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall attrs.getList()); 141174256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall 141274256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // Friend template-ids are treated as references unless 141374256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // they have template headers, in which case they're ill-formed 141474256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // (FIXME: "template <class T> friend class A<T>::B<int>;"). 141574256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // We diagnose this error in ActOnClassTemplateSpecialization. 1416f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall } else if (TUK == Sema::TUK_Reference || 1417f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall (TUK == Sema::TUK_Friend && 141874256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) { 14192edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 142055d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara TypeResult = Actions.ActOnTagTemplateIdType(TUK, TagType, StartLoc, 1421059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->SS, 142255d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara TemplateId->TemplateKWLoc, 1423059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->Template, 1424059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->TemplateNameLoc, 1425059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->LAngleLoc, 1426059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateArgsPtr, 142755d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara TemplateId->RAngleLoc); 14284d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor } else { 14294d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // This is an explicit specialization or a class template 14304d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // partial specialization. 14314d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TemplateParameterLists FakedParamLists; 14324d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 14334d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { 14344d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // This looks like an explicit instantiation, because we have 14354d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // something like 14364d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // 14374d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // template class Foo<X> 14384d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // 14393f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // but it actually has a definition. Most likely, this was 14404d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // meant to be an explicit specialization, but the user forgot 14414d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // the '<>' after 'template'. 1442f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall assert(TUK == Sema::TUK_Definition && "Expected a definition here"); 14434d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 14441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump SourceLocation LAngleLoc 14454d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc); 14461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(TemplateId->TemplateNameLoc, 14474d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor diag::err_explicit_instantiation_with_definition) 14484d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor << SourceRange(TemplateInfo.TemplateLoc) 1449849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor << FixItHint::CreateInsertion(LAngleLoc, "<>"); 14504d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 14514d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // Create a fake template parameter list that contains only 14524d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // "template<>", so that we treat this construct as a class 14534d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // template specialization. 14544d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor FakedParamLists.push_back( 14551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Actions.ActOnTemplateParameterList(0, SourceLocation(), 14564d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TemplateInfo.TemplateLoc, 14571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump LAngleLoc, 14581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 0, 0, 14594d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor LAngleLoc)); 14604d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TemplateParams = &FakedParamLists; 14614d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor } 14624d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 14634d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // Build the class template specialization. 14644d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TagOrTempResult 146523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK, 1466d023aec8907831a18d3514a95b843a7ee06b6b5eDouglas Gregor StartLoc, DS.getModulePrivateSpecLoc(), SS, 14672b5289b6fd7e3d9899868410a498c081c9595662John McCall TemplateId->Template, 14681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->TemplateNameLoc, 14691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->LAngleLoc, 147039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateArgsPtr, 14711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->RAngleLoc, 14727f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall attrs.getList(), 14735354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer MultiTemplateParamsArg( 1474cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor TemplateParams? &(*TemplateParams)[0] : 0, 1475cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor TemplateParams? TemplateParams->size() : 0)); 14764d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor } 14773f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && 1478f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK == Sema::TUK_Declaration) { 14793f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // Explicit instantiation of a member of a class template 14803f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // specialization, e.g., 14813f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // 14823f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // template struct Outer<int>::Inner; 14833f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // 14842edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 14852edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 14863f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor TagOrTempResult 148723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnExplicitInstantiation(getCurScope(), 148845f965581935791a018df829a14dff53c1dd8f47Douglas Gregor TemplateInfo.ExternLoc, 14891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateInfo.TemplateLoc, 14901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TagType, StartLoc, SS, Name, 14917f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall NameLoc, attrs.getList()); 14929a34edb710917798aa30263374f624f13b594605John McCall } else if (TUK == Sema::TUK_Friend && 14939a34edb710917798aa30263374f624f13b594605John McCall TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) { 14942edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 14952edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 14969a34edb710917798aa30263374f624f13b594605John McCall TagOrTempResult = 14979a34edb710917798aa30263374f624f13b594605John McCall Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(), 14989a34edb710917798aa30263374f624f13b594605John McCall TagType, StartLoc, SS, 14997f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall Name, NameLoc, attrs.getList(), 15005354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer MultiTemplateParamsArg( 15019a34edb710917798aa30263374f624f13b594605John McCall TemplateParams? &(*TemplateParams)[0] : 0, 15029a34edb710917798aa30263374f624f13b594605John McCall TemplateParams? TemplateParams->size() : 0)); 15033f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor } else { 15042edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition) 15052edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 15062edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 1507c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall bool IsDependent = false; 1508c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall 1509a25c4080a490ea2bab6f54094dd75b19eae83770John McCall // Don't pass down template parameter lists if this is just a tag 1510a25c4080a490ea2bab6f54094dd75b19eae83770John McCall // reference. For example, we don't need the template parameters here: 1511a25c4080a490ea2bab6f54094dd75b19eae83770John McCall // template <class T> class A *makeA(T t); 1512a25c4080a490ea2bab6f54094dd75b19eae83770John McCall MultiTemplateParamsArg TParams; 1513a25c4080a490ea2bab6f54094dd75b19eae83770John McCall if (TUK != Sema::TUK_Reference && TemplateParams) 1514a25c4080a490ea2bab6f54094dd75b19eae83770John McCall TParams = 1515a25c4080a490ea2bab6f54094dd75b19eae83770John McCall MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size()); 1516a25c4080a490ea2bab6f54094dd75b19eae83770John McCall 15173f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // Declaration or definition of a class type 15189a34edb710917798aa30263374f624f13b594605John McCall TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc, 15197f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall SS, Name, NameLoc, attrs.getList(), AS, 1520e761230ae3751b525cadd8066c74ec278ee4ef57Douglas Gregor DS.getModulePrivateSpecLoc(), 1521bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith TParams, Owned, IsDependent, 1522bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith SourceLocation(), false, 1523bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith clang::TypeResult()); 1524c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall 1525c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall // If ActOnTag said the type was dependent, try again with the 1526c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall // less common call. 15279a34edb710917798aa30263374f624f13b594605John McCall if (IsDependent) { 15289a34edb710917798aa30263374f624f13b594605John McCall assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend); 152923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK, 1530193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam SS, Name, StartLoc, NameLoc); 15319a34edb710917798aa30263374f624f13b594605John McCall } 15323f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor } 1533e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1534e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If there is a body, parse it and inform the actions module. 1535f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall if (TUK == Sema::TUK_Definition) { 1536bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall assert(Tok.is(tok::l_brace) || 15374e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie (getLangOpts().CPlusPlus && Tok.is(tok::colon)) || 15384e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith isCXX11FinalKeyword()); 15394e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus) 154007fc1ba7553f2f5bf26984091197311decd9028eMichael Han ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs, TagType, 154107fc1ba7553f2f5bf26984091197311decd9028eMichael Han TagOrTempResult.get()); 154207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis else 1543212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get()); 1544e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1545e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1546b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall const char *PrevSpec = 0; 1547b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall unsigned DiagID; 1548b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall bool Result; 1549c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall if (!TypeResult.isInvalid()) { 15500daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, 15510daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara NameLoc.isValid() ? NameLoc : StartLoc, 1552b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall PrevSpec, DiagID, TypeResult.get()); 1553c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall } else if (!TagOrTempResult.isInvalid()) { 15540daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara Result = DS.SetTypeSpecType(TagType, StartLoc, 15550daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara NameLoc.isValid() ? NameLoc : StartLoc, 15560daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara PrevSpec, DiagID, TagOrTempResult.get(), Owned); 1557c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall } else { 1558ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor DS.SetTypeSpecError(); 155966e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson return; 156066e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson } 15611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1562b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall if (Result) 1563fec54013fcd0eb72642741584ca04c1bc292bef8John McCall Diag(StartLoc, DiagID) << PrevSpec; 1564193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 15654ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // At this point, we've successfully parsed a class-specifier in 'definition' 15664ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // form (e.g. "struct foo { int x; }". While we could just return here, we're 15674ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // going to look at what comes after it to improve error recovery. If an 15684ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // impossible token occurs next, we assume that the programmer forgot a ; at 15694ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // the end of the declaration and recover that way. 15704ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // 1571c9f351700721150a985f21844fbfec55b04e861dRichard Smith // Also enforce C++ [temp]p3: 1572c9f351700721150a985f21844fbfec55b04e861dRichard Smith // In a template-declaration which defines a class, no declarator 1573c9f351700721150a985f21844fbfec55b04e861dRichard Smith // is permitted. 157417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos if (TUK == Sema::TUK_Definition && 157517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) { 15767d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis if (Tok.isNot(tok::semi)) { 15777d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, 15787d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis DeclSpec::getSpecifierName(TagType)); 15797d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis // Push this token back into the preprocessor and change our current token 15807d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis // to ';' so that the rest of the code recovers as though there were an 15817d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis // ';' after the definition. 15827d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis PP.EnterToken(Tok); 15837d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis Tok.setKind(tok::semi); 15847d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis } 15854ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner } 1586e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 1587e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 15881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived]. 1589e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1590e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-clause : [C++ class.derived] 1591e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ':' base-specifier-list 1592e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier-list: 1593e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier '...'[opt] 1594e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier-list ',' base-specifier '...'[opt] 1595d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseBaseClause(Decl *ClassDecl) { 1596e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor assert(Tok.is(tok::colon) && "Not a base clause"); 1597e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 1598e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1599f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Build up an array of parsed base specifiers. 16005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CXXBaseSpecifier *, 8> BaseInfo; 1601f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor 1602e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor while (true) { 1603e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse a base-specifier. 1604f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor BaseResult Result = ParseBaseSpecifier(ClassDecl); 16055ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor if (Result.isInvalid()) { 1606e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Skip the rest of this base specifier, up until the comma or 1607e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // opening brace. 1608f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor SkipUntil(tok::comma, tok::l_brace, true, true); 1609f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor } else { 1610f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Add this to our array of base specifiers. 16115ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor BaseInfo.push_back(Result.get()); 1612e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1613e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1614e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If the next token is a comma, consume it and keep reading 1615e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // base-specifiers. 1616e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.isNot(tok::comma)) break; 16171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1618e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Consume the comma. 1619e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 1620e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1621f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor 1622f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Attach the base specifiers 1623beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size()); 1624e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 1625e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1626e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is 1627e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example: 1628e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class foo : public bar, virtual private baz { 1629e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers. 1630e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1631e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier: [C++ class.derived] 1632053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// attribute-specifier-seq[opt] base-type-specifier 1633053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// attribute-specifier-seq[opt] 'virtual' access-specifier[opt] 1634053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// base-type-specifier 1635053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// attribute-specifier-seq[opt] access-specifier 'virtual'[opt] 1636053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// base-type-specifier 1637d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) { 1638e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor bool IsVirtual = false; 1639e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation StartLoc = Tok.getLocation(); 1640e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1641053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith ParsedAttributesWithRange Attributes(AttrFactory); 1642053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith MaybeParseCXX11Attributes(Attributes); 1643053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith 1644e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the 'virtual' keyword. 1645e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw_virtual)) { 1646e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 1647e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IsVirtual = true; 1648e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1649e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1650053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith CheckMisplacedCXX11Attribute(Attributes, StartLoc); 1651053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith 1652e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse an (optional) access specifier. 1653e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor AccessSpecifier Access = getAccessSpecifierIfPresent(); 165492f883177b162928a8e632e4e3b93fafd2b26072John McCall if (Access != AS_none) 1655e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 16561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1657053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith CheckMisplacedCXX11Attribute(Attributes, StartLoc); 1658053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith 1659e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the 'virtual' keyword (again!), in case it came after the 1660e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // access specifier. 1661e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw_virtual)) { 1662e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation VirtualLoc = ConsumeToken(); 1663e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (IsVirtual) { 1664e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Complain about duplicate 'virtual' 16651ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(VirtualLoc, diag::err_dup_virtual) 1666849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor << FixItHint::CreateRemoval(VirtualLoc); 1667e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1668e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1669e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IsVirtual = true; 1670e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1671e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1672053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith CheckMisplacedCXX11Attribute(Attributes, StartLoc); 1673053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith 167442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Parse the class-name. 16757f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor SourceLocation EndLocation; 167622216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie SourceLocation BaseLoc; 167722216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation); 167831a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor if (BaseType.isInvalid()) 167942a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return true; 16801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1681f90b27ad077c3339b62befc892382845339f9490Douglas Gregor // Parse the optional ellipsis (for a pack expansion). The ellipsis is 1682f90b27ad077c3339b62befc892382845339f9490Douglas Gregor // actually part of the base-specifier-list grammar productions, but we 1683f90b27ad077c3339b62befc892382845339f9490Douglas Gregor // parse it here for convenience. 1684f90b27ad077c3339b62befc892382845339f9490Douglas Gregor SourceLocation EllipsisLoc; 1685f90b27ad077c3339b62befc892382845339f9490Douglas Gregor if (Tok.is(tok::ellipsis)) 1686f90b27ad077c3339b62befc892382845339f9490Douglas Gregor EllipsisLoc = ConsumeToken(); 1687f90b27ad077c3339b62befc892382845339f9490Douglas Gregor 16881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Find the complete source range for the base-specifier. 16897f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor SourceRange Range(StartLoc, EndLocation); 16901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1691e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Notify semantic analysis that we have parsed a complete 1692e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // base-specifier. 1693053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith return Actions.ActOnBaseSpecifier(ClassDecl, Range, Attributes, IsVirtual, 1694053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith Access, BaseType.get(), BaseLoc, 1695053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith EllipsisLoc); 1696e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 1697e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1698e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is 1699e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier. 1700e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1701e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// access-specifier: [C++ class.derived] 1702e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'private' 1703e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'protected' 1704e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public' 17051eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAccessSpecifier Parser::getAccessSpecifierIfPresent() const { 1706e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor switch (Tok.getKind()) { 1707e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor default: return AS_none; 1708e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_private: return AS_private; 1709e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_protected: return AS_protected; 1710e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_public: return AS_public; 1711e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1712e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 17134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 171474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor/// \brief If the given declarator has any parts for which parsing has to be 1715a058fd4f0a944174295f77169b438510dad389f8Richard Smith/// delayed, e.g., default arguments, create a late-parsed method declaration 1716a058fd4f0a944174295f77169b438510dad389f8Richard Smith/// record to handle the parsing at the end of the class definition. 171774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregorvoid Parser::HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo, 171874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor Decl *ThisDecl) { 1719d33133cdc1af466f9c276249b2621be03867888bEli Friedman // We just declared a member function. If this member function 1720a058fd4f0a944174295f77169b438510dad389f8Richard Smith // has any default arguments, we'll need to parse them later. 1721d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateParsedMethodDeclaration *LateMethod = 0; 17221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump DeclaratorChunk::FunctionTypeInfo &FTI 1723075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara = DeclaratorInfo.getFunctionTypeInfo(); 172474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 1725d33133cdc1af466f9c276249b2621be03867888bEli Friedman for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) { 1726d33133cdc1af466f9c276249b2621be03867888bEli Friedman if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) { 1727d33133cdc1af466f9c276249b2621be03867888bEli Friedman if (!LateMethod) { 1728d33133cdc1af466f9c276249b2621be03867888bEli Friedman // Push this method onto the stack of late-parsed method 1729d33133cdc1af466f9c276249b2621be03867888bEli Friedman // declarations. 1730d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor LateMethod = new LateParsedMethodDeclaration(this, ThisDecl); 1731d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor getCurrentClass().LateParsedDeclarations.push_back(LateMethod); 173223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor LateMethod->TemplateScope = getCurScope()->isTemplateParamScope(); 1733d33133cdc1af466f9c276249b2621be03867888bEli Friedman 1734d33133cdc1af466f9c276249b2621be03867888bEli Friedman // Add all of the parameters prior to this one (they don't 1735d33133cdc1af466f9c276249b2621be03867888bEli Friedman // have default arguments). 1736d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateMethod->DefaultArgs.reserve(FTI.NumArgs); 1737d33133cdc1af466f9c276249b2621be03867888bEli Friedman for (unsigned I = 0; I < ParamIdx; ++I) 1738d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateMethod->DefaultArgs.push_back( 17398f8210c47797f013e0fb24a26f9c4751b10783feDouglas Gregor LateParsedDefaultArgument(FTI.ArgInfo[I].Param)); 1740d33133cdc1af466f9c276249b2621be03867888bEli Friedman } 1741d33133cdc1af466f9c276249b2621be03867888bEli Friedman 174274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Add this parameter to the list of parameters (it may or may 1743d33133cdc1af466f9c276249b2621be03867888bEli Friedman // not have a default argument). 1744d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateMethod->DefaultArgs.push_back( 1745d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param, 1746d33133cdc1af466f9c276249b2621be03867888bEli Friedman FTI.ArgInfo[ParamIdx].DefaultArgTokens)); 1747d33133cdc1af466f9c276249b2621be03867888bEli Friedman } 1748d33133cdc1af466f9c276249b2621be03867888bEli Friedman } 1749d33133cdc1af466f9c276249b2621be03867888bEli Friedman} 1750d33133cdc1af466f9c276249b2621be03867888bEli Friedman 17514e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith/// isCXX11VirtSpecifier - Determine whether the given token is a C++11 17521f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier. 17531f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 17541f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier: 17551f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// override 17561f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// final 17574e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard SmithVirtSpecifiers::Specifier Parser::isCXX11VirtSpecifier(const Token &Tok) const { 17584e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().CPlusPlus) 1759cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson return VirtSpecifiers::VS_None; 1760cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 1761b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (Tok.is(tok::identifier)) { 1762b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson IdentifierInfo *II = Tok.getIdentifierInfo(); 17631f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 17647eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson // Initialize the contextual keywords. 17657eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson if (!Ident_final) { 17667eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson Ident_final = &PP.getIdentifierTable().get("final"); 17677eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson Ident_override = &PP.getIdentifierTable().get("override"); 17687eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson } 17697eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson 1770b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (II == Ident_override) 1771b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return VirtSpecifiers::VS_Override; 17721f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 1773b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (II == Ident_final) 1774b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return VirtSpecifiers::VS_Final; 1775b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson } 1776b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson 1777b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return VirtSpecifiers::VS_None; 17781f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson} 17791f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 17804e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith/// ParseOptionalCXX11VirtSpecifierSeq - Parse a virt-specifier-seq. 17811f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 17821f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq: 17831f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier 17841f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq virt-specifier 17854e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smithvoid Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS, 1786e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall bool IsInterface) { 1787b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson while (true) { 17884e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier(); 1789b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (Specifier == VirtSpecifiers::VS_None) 1790b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return; 1791b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson 1792b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson // C++ [class.mem]p8: 1793b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson // A virt-specifier-seq shall contain at most one of each virt-specifier. 1794cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson const char *PrevSpec = 0; 179546127a96b6dd6b93aa18d5f7a55bc2db8b52a2c9Anders Carlsson if (VS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec)) 1796b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier) 1797b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson << PrevSpec 1798b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson << FixItHint::CreateRemoval(Tok.getLocation()); 1799b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson 1800e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall if (IsInterface && Specifier == VirtSpecifiers::VS_Final) { 1801e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall Diag(Tok.getLocation(), diag::err_override_control_interface) 1802e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall << VirtSpecifiers::getSpecifierName(Specifier); 1803e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall } else { 180480ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith Diag(Tok.getLocation(), getLangOpts().CPlusPlus11 ? 1805e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall diag::warn_cxx98_compat_override_control_keyword : 1806e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall diag::ext_override_control_keyword) 1807e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall << VirtSpecifiers::getSpecifierName(Specifier); 1808e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall } 1809b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson ConsumeToken(); 1810b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson } 18111f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson} 18121f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 18134e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith/// isCXX11FinalKeyword - Determine whether the next token is a C++11 18148a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson/// contextual 'final' keyword. 18154e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smithbool Parser::isCXX11FinalKeyword() const { 18164e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().CPlusPlus) 18178a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson return false; 1818cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 18198a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson if (!Tok.is(tok::identifier)) 18208a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson return false; 1821cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 18228a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson // Initialize the contextual keywords. 18238a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson if (!Ident_final) { 18248a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson Ident_final = &PP.getIdentifierTable().get("final"); 18258a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson Ident_override = &PP.getIdentifierTable().get("override"); 1826cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson } 18278a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson 18288a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson return Tok.getIdentifierInfo() == Ident_final; 1829cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson} 1830cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 18314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration. 18324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 18334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declaration: 18344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// decl-specifier-seq[opt] member-declarator-list[opt] ';' 18354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// function-definition ';'[opt] 18364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO] 18374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// using-declaration [TODO] 1838511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration 18395aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson/// template-declaration 1840bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU] '__extension__' member-declaration 18414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 18424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator-list: 18434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator 18444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator-list ',' member-declarator 18454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 18464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator: 18471f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// declarator virt-specifier-seq[opt] pure-specifier[opt] 18484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// declarator constant-initializer[opt] 18497a614d8380297fcd2bc23986241905d97222948cRichard Smith/// [C++11] declarator brace-or-equal-initializer[opt] 18504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// identifier[opt] ':' constant-expression 18514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 18521f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq: 18531f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier 18541f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq virt-specifier 18551f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 18561f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier: 18571f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// override 18581f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// final 18591f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 1860e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl/// pure-specifier: 18614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// '= 0' 18624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 18634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// constant-initializer: 18644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// '=' constant-expression 18654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 186637b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregorvoid Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, 18675f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen AttributeList *AccessAttrs, 1868c9068d7dd94d439cec66c421115d15303e481025John McCall const ParsedTemplateInfo &TemplateInfo, 1869c9068d7dd94d439cec66c421115d15303e481025John McCall ParsingDeclRAIIObject *TemplateDiags) { 18708a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor if (Tok.is(tok::at)) { 18714e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjC1 && NextToken().isObjCAtKeyword(tok::objc_defs)) 18728a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor Diag(Tok, diag::err_at_defs_cxx); 18738a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor else 18748a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor Diag(Tok, diag::err_at_in_class); 18758a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor 18768a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor ConsumeToken(); 18778a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor SkipUntil(tok::r_brace); 18788a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor return; 18798a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor } 18808a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor 188160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // Access declarations. 188283a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith bool MalformedTypeSpec = false; 188360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall if (!TemplateInfo.Kind && 188483a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith (Tok.is(tok::identifier) || Tok.is(tok::coloncolon))) { 188583a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith if (TryAnnotateCXXScopeToken()) 188683a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith MalformedTypeSpec = true; 188783a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith 188883a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith bool isAccessDecl; 188983a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith if (Tok.isNot(tok::annot_cxxscope)) 189083a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith isAccessDecl = false; 189183a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith else if (NextToken().is(tok::identifier)) 189260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall isAccessDecl = GetLookAheadToken(2).is(tok::semi); 189360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall else 189460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall isAccessDecl = NextToken().is(tok::kw_operator); 189560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 189660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall if (isAccessDecl) { 189760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // Collect the scope specifier token we annotated earlier. 189860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall CXXScopeSpec SS; 1899efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 1900efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor /*EnteringContext=*/false); 190160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 190260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // Try to parse an unqualified-id. 1903e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara SourceLocation TemplateKWLoc; 190460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall UnqualifiedId Name; 1905e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), 1906e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara TemplateKWLoc, Name)) { 190760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall SkipUntil(tok::semi); 190860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall return; 190960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall } 191060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 191160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // TODO: recover from mistakenly-qualified operator declarations. 191260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall if (ExpectAndConsume(tok::semi, 191360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall diag::err_expected_semi_after, 191460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall "access declaration", 191560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall tok::semi)) 191660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall return; 191760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 191823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnUsingDeclaration(getCurScope(), AS, 191960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall false, SourceLocation(), 192060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall SS, Name, 192160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall /* AttrList */ 0, 192260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall /* IsTypeName */ false, 192360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall SourceLocation()); 192460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall return; 192560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall } 192660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall } 192760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 1928511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson // static_assert-declaration 1929c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne if (Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) { 193037b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor // FIXME: Check for templates 193197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner SourceLocation DeclEnd; 193297144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner ParseStaticAssertDeclaration(DeclEnd); 1933682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 1934682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner } 19351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1936682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner if (Tok.is(tok::kw_template)) { 19371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump assert(!TemplateInfo.TemplateParams && 193837b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor "Nested template improperly parsed?"); 193997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner SourceLocation DeclEnd; 19401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd, 19415f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen AS, AccessAttrs); 1942682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 1943682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner } 19445aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson 1945bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner // Handle: member-declaration ::= '__extension__' member-declaration 1946bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner if (Tok.is(tok::kw___extension__)) { 1947bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner // __extension__ silences extension warnings in the subexpression. 1948bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner ExtensionRAIIObject O(Diags); // Use RAII to do this. 1949bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner ConsumeToken(); 19505f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen return ParseCXXClassMemberDeclaration(AS, AccessAttrs, 19515f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen TemplateInfo, TemplateDiags); 1952bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner } 19539cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 19544ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it 19554ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // is a bitfield. 1956a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner ColonProtectionRAIIObject X(*this); 1957193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 19580b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributesWithRange attrs(AttrFactory); 195952b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han ParsedAttributesWithRange FnAttrs(AttrFactory); 19604e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith // Optional C++11 attribute-specifier 19614e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith MaybeParseCXX11Attributes(attrs); 196252b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // We need to keep these attributes for future diagnostic 196352b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // before they are taken over by declaration specifier. 196452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han FnAttrs.addAll(attrs.getList()); 196552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han FnAttrs.Range = attrs.Range; 196652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han 19677f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseMicrosoftAttributes(attrs); 1968bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 19699cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (Tok.is(tok::kw_using)) { 19707f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ProhibitAttributes(attrs); 19711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 19729cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Eat 'using'. 19739cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SourceLocation UsingLoc = ConsumeToken(); 19749cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 19759cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (Tok.is(tok::kw_namespace)) { 19769cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor Diag(UsingLoc, diag::err_using_namespace_in_class); 19779cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SkipUntil(tok::semi, true, true); 1978ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner } else { 19799cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SourceLocation DeclEnd; 19803e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // Otherwise, it must be a using-declaration or an alias-declaration. 198178b810559d89e996e00684335407443936ce34a1John McCall ParseUsingDeclaration(Declarator::MemberContext, TemplateInfo, 198278b810559d89e996e00684335407443936ce34a1John McCall UsingLoc, DeclEnd, AS); 19839cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 19849cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor return; 19859cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 19869cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 19872287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins // Hold late-parsed attributes so we can attach a Decl to them later. 19882287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins LateParsedAttrList CommonLateParsedAttrs; 19892287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins 19904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // decl-specifier-seq: 19914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the common declaration-specifiers piece. 1992c9068d7dd94d439cec66c421115d15303e481025John McCall ParsingDeclSpec DS(*this, TemplateDiags); 19937f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall DS.takeAttributesFrom(attrs); 199483a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith if (MalformedTypeSpec) 199583a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith DS.SetTypeSpecError(); 19962287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class, 19972287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins &CommonLateParsedAttrs); 19984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 19995354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer MultiTemplateParamsArg TemplateParams( 2000dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0, 2001dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0); 2002dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall 20034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) { 20044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 200552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han 200652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han if (DS.isFriendSpecified()) 200752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han ProhibitAttributes(FnAttrs); 200852b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han 2009d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl *TheDecl = 20100f4be74ff0273e505d383f89174ef539828424edChandler Carruth Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS, TemplateParams); 2011c9068d7dd94d439cec66c421115d15303e481025John McCall DS.complete(TheDecl); 201267d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall return; 20134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 201407952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis 201554abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext); 20164867347e82648d3baf09524b98b09c297a5a198fNico Weber VirtSpecifiers VS; 20174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 2018eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // Hold late-parsed attributes so we can attach a Decl to them later. 2019eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski LateParsedAttrList LateParsedAttrs; 2020eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski 2021a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor SourceLocation EqualLoc; 2022a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor bool HasInitializer = false; 2023a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor ExprResult Init; 20243a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.isNot(tok::colon)) { 2025a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 2026a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner ColonProtectionRAIIObject X(*this); 2027a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner 20283a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // Parse the first declarator. 20293a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 2030a058fd4f0a944174295f77169b438510dad389f8Richard Smith // Error parsing the declarator? 203110bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor if (!DeclaratorInfo.hasName()) { 20323a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // If so, skip until the semi-colon or a }. 2033d941fa4ff0d0d64b5a541dbd4f99693bff7f6e8dSebastian Redl SkipUntil(tok::r_brace, true, true); 20343a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.is(tok::semi)) 20353a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeToken(); 2036682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 20374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 20384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 20394e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith ParseOptionalCXX11VirtSpecifierSeq(VS, getCurrentClass().IsInterface); 20404867347e82648d3baf09524b98b09c297a5a198fNico Weber 20411b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson // If attributes exist after the declarator, but before an '{', parse them. 2042eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); 20431b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson 20446a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet // MSVC permits pure specifier on inline functions declared at class scope. 20456a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet // Hence check for =0 before checking for function definition. 20464e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().MicrosoftExt && Tok.is(tok::equal) && 20476a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet DeclaratorInfo.isFunctionDeclarator() && 20486a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet NextToken().is(tok::numeric_constant)) { 2049a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor EqualLoc = ConsumeToken(); 20506a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet Init = ParseInitializer(); 20516a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet if (Init.isInvalid()) 20526a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet SkipUntil(tok::comma, true, true); 2053a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor else 2054a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor HasInitializer = true; 20556a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet } 20566a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet 205745fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor FunctionDefinitionKind DefinitionKind = FDK_Declaration; 20583a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // function-definition: 20597a614d8380297fcd2bc23986241905d97222948cRichard Smith // 20607a614d8380297fcd2bc23986241905d97222948cRichard Smith // In C++11, a non-function declarator followed by an open brace is a 20617a614d8380297fcd2bc23986241905d97222948cRichard Smith // braced-init-list for an in-class member initialization, not an 20627a614d8380297fcd2bc23986241905d97222948cRichard Smith // erroneous function definition. 206380ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (Tok.is(tok::l_brace) && !getLangOpts().CPlusPlus11) { 206445fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Definition; 2065e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } else if (DeclaratorInfo.isFunctionDeclarator()) { 20667a614d8380297fcd2bc23986241905d97222948cRichard Smith if (Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) { 206745fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Definition; 2068e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } else if (Tok.is(tok::equal)) { 2069e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt const Token &KW = NextToken(); 207045fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor if (KW.is(tok::kw_default)) 207145fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Defaulted; 207245fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor else if (KW.is(tok::kw_delete)) 207345fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Deleted; 2074e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } 2075e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } 2076e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt 207752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains 207852b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // to a friend declaration, that declaration shall be a definition. 207952b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han if (DeclaratorInfo.isFunctionDeclarator() && 208052b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han DefinitionKind != FDK_Definition && DS.isFriendSpecified()) { 208152b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // Diagnose attributes that appear before decl specifier: 208252b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // [[]] friend int foo(); 208352b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han ProhibitAttributes(FnAttrs); 208452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han } 208552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han 208645fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor if (DefinitionKind) { 20873a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (!DeclaratorInfo.isFunctionDeclarator()) { 208865ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params); 20893a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeBrace(); 209065ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu SkipUntil(tok::r_brace, /*StopAtSemi*/false); 209152b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han 20929ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor // Consume the optional ';' 20939ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor if (Tok.is(tok::semi)) 20949ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor ConsumeToken(); 2095682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 20963a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 20973a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis 20983a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 209965ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu Diag(DeclaratorInfo.getIdentifierLoc(), 210065ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu diag::err_function_declared_typedef); 21019ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor 21026f9a445760992a6fbff2c0b08becf35ae9eafa71Richard Smith // Recover by treating the 'typedef' as spurious. 21036f9a445760992a6fbff2c0b08becf35ae9eafa71Richard Smith DS.ClearStorageClassSpecs(); 21043a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 21054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 2106eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski Decl *FunDecl = 21075f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo, TemplateInfo, 210845fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor VS, DefinitionKind, Init); 2109eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski 21102287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) { 21112287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins CommonLateParsedAttrs[i]->addDecl(FunDecl); 21122287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins } 2113eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) { 21142287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins LateParsedAttrs[i]->addDecl(FunDecl); 2115eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski } 2116eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski LateParsedAttrs.clear(); 2117e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt 2118e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt // Consume the ';' - it's optional unless we have a delete or default 21194b0e6f1da341510c1ad83eaf4c836f3134d0156aRichard Trieu if (Tok.is(tok::semi)) 2120eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith ConsumeExtraSemi(AfterMemberFunctionDefinition); 21219ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor 2122682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 21233a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 21244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 21254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 21264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator-list: 21274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator 21284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator-list ',' member-declarator 21294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 21305f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Decl *, 8> DeclsInGroup; 213160d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult BitfieldSize; 21321c94c16317c1a35c1549e022958188eea2567089Richard Smith bool ExpectSemi = true; 21334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 21344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis while (1) { 21354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator: 21364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // declarator pure-specifier[opt] 21377a614d8380297fcd2bc23986241905d97222948cRichard Smith // declarator brace-or-equal-initializer[opt] 21384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // identifier[opt] ':' constant-expression 21394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::colon)) { 21404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 21410e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl BitfieldSize = ParseConstantExpression(); 21420e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (BitfieldSize.isInvalid()) 21434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::comma, true, true); 21444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 21451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2146e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner // If a simple-asm-expr is present, parse it. 2147e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner if (Tok.is(tok::kw_asm)) { 2148e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner SourceLocation Loc; 214960d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AsmLabel(ParseSimpleAsm(&Loc)); 2150e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner if (AsmLabel.isInvalid()) 2151e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner SkipUntil(tok::comma, true, true); 2152e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner 2153e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner DeclaratorInfo.setAsmLabel(AsmLabel.release()); 2154e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner DeclaratorInfo.SetRangeEnd(Loc); 2155e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner } 2156e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner 21574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If attributes exist after the declarator, parse them. 2158eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); 21594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 21607a614d8380297fcd2bc23986241905d97222948cRichard Smith // FIXME: When g++ adds support for this, we'll need to check whether it 21617a614d8380297fcd2bc23986241905d97222948cRichard Smith // goes before or after the GNU attributes and __asm__. 21624e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith ParseOptionalCXX11VirtSpecifierSeq(VS, getCurrentClass().IsInterface); 21637a614d8380297fcd2bc23986241905d97222948cRichard Smith 2164ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith InClassInitStyle HasInClassInit = ICIS_NoInit; 2165a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor if ((Tok.is(tok::equal) || Tok.is(tok::l_brace)) && !HasInitializer) { 21667a614d8380297fcd2bc23986241905d97222948cRichard Smith if (BitfieldSize.get()) { 21677a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(Tok, diag::err_bitfield_member_init); 21687a614d8380297fcd2bc23986241905d97222948cRichard Smith SkipUntil(tok::comma, true, true); 21697a614d8380297fcd2bc23986241905d97222948cRichard Smith } else { 2170147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor HasInitializer = true; 2171ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith if (!DeclaratorInfo.isDeclarationOfFunction() && 2172ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith DeclaratorInfo.getDeclSpec().getStorageClassSpec() 2173ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith != DeclSpec::SCS_typedef) 2174ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith HasInClassInit = Tok.is(tok::equal) ? ICIS_CopyInit : ICIS_ListInit; 21757a614d8380297fcd2bc23986241905d97222948cRichard Smith } 21767a614d8380297fcd2bc23986241905d97222948cRichard Smith } 21777a614d8380297fcd2bc23986241905d97222948cRichard Smith 217807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // NOTE: If Sema is the Action module and declarator is an instance field, 2179682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner // this call will *not* return the created decl; It will return null. 218007952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // See Sema::ActOnCXXMemberDeclarator for details. 218167d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall 2182fc35cbca942ccdfe43742c1d786ed168517e0a47Rafael Espindola NamedDecl *ThisDecl = 0; 218367d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall if (DS.isFriendSpecified()) { 218452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains 218552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // to a friend declaration, that declaration shall be a definition. 218652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // 218752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // Diagnose attributes appear after friend member function declarator: 218852b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // foo [[]] (); 218952b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han SmallVector<SourceRange, 4> Ranges; 219052b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han DeclaratorInfo.getCXX11AttributeRanges(Ranges); 219152b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han if (!Ranges.empty()) { 219252b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han for (SmallVector<SourceRange, 4>::iterator I = Ranges.begin(), 219352b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han E = Ranges.end(); I != E; ++I) { 219452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han Diag((*I).getBegin(), diag::err_attributes_not_allowed) 219552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han << *I; 219652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han } 219752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han } 219852b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han 2199bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall // TODO: handle initializers, bitfields, 'delete' 220023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo, 22013fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer TemplateParams); 220237b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor } else { 220323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, 220467d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall DeclaratorInfo, 22053fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer TemplateParams, 220667d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall BitfieldSize.release(), 2207ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith VS, HasInClassInit); 22085f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen if (AccessAttrs) 22095f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs, 22105f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen false, true); 221137b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor } 2212147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor 2213eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // Set the Decl for any late parsed attributes 22142287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) { 22152287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins CommonLateParsedAttrs[i]->addDecl(ThisDecl); 22162287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins } 2217eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) { 22182287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins LateParsedAttrs[i]->addDecl(ThisDecl); 2219eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski } 2220eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski LateParsedAttrs.clear(); 2221eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski 2222147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // Handle the initializer. 22231d87fbaeea4a9fbbd73b3a53641f59f1673098e5David Blaikie if (HasInClassInit != ICIS_NoInit && 22241d87fbaeea4a9fbbd73b3a53641f59f1673098e5David Blaikie DeclaratorInfo.getDeclSpec().getStorageClassSpec() != 22251d87fbaeea4a9fbbd73b3a53641f59f1673098e5David Blaikie DeclSpec::SCS_static) { 2226147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // The initializer was deferred; parse it and cache the tokens. 222780ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith Diag(Tok, getLangOpts().CPlusPlus11 ? 22287fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_nonstatic_member_init : 22297fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::ext_nonstatic_member_init); 22307fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 22317a614d8380297fcd2bc23986241905d97222948cRichard Smith if (DeclaratorInfo.isArrayOfUnknownBound()) { 2232ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith // C++11 [dcl.array]p3: An array bound may also be omitted when the 2233ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith // declarator is followed by an initializer. 22347a614d8380297fcd2bc23986241905d97222948cRichard Smith // 22357a614d8380297fcd2bc23986241905d97222948cRichard Smith // A brace-or-equal-initializer for a member-declarator is not an 22363164c14cadbb09a05ba811602221e9156077cf44David Blaikie // initializer in the grammar, so this is ill-formed. 22377a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(Tok, diag::err_incomplete_array_member_init); 22387a614d8380297fcd2bc23986241905d97222948cRichard Smith SkipUntil(tok::comma, true, true); 22393164c14cadbb09a05ba811602221e9156077cf44David Blaikie if (ThisDecl) 22403164c14cadbb09a05ba811602221e9156077cf44David Blaikie // Avoid later warnings about a class member of incomplete type. 22413164c14cadbb09a05ba811602221e9156077cf44David Blaikie ThisDecl->setInvalidDecl(); 22427a614d8380297fcd2bc23986241905d97222948cRichard Smith } else 22437a614d8380297fcd2bc23986241905d97222948cRichard Smith ParseCXXNonStaticMemberInitializer(ThisDecl); 2244147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor } else if (HasInitializer) { 2245147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // Normal initializer. 2246a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor if (!Init.isUsable()) 2247552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor Init = ParseCXXMemberInitializer(ThisDecl, 2248a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor DeclaratorInfo.isDeclarationOfFunction(), EqualLoc); 2249a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor 2250147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor if (Init.isInvalid()) 2251147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor SkipUntil(tok::comma, true, true); 2252147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor else if (ThisDecl) 225333deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid(), 2254a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor DS.getTypeSpecType() == DeclSpec::TST_auto); 2255147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static) { 2256147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // No initializer. 2257147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor Actions.ActOnUninitializedDecl(ThisDecl, 2258147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor DS.getTypeSpecType() == DeclSpec::TST_auto); 22597a614d8380297fcd2bc23986241905d97222948cRichard Smith } 2260147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor 2261147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor if (ThisDecl) { 2262147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor Actions.FinalizeDeclaration(ThisDecl); 2263147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor DeclsInGroup.push_back(ThisDecl); 2264147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor } 2265147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor 2266e531001b7e44bee5c4ec0be93efbc75adb37a0e3Richard Smith if (ThisDecl && DeclaratorInfo.isFunctionDeclarator() && 2267147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor DeclaratorInfo.getDeclSpec().getStorageClassSpec() 2268147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor != DeclSpec::SCS_typedef) { 226974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl); 2270147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor } 2271147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor 2272147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor DeclaratorInfo.complete(ThisDecl); 22737a614d8380297fcd2bc23986241905d97222948cRichard Smith 22744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If we don't have a comma, it is either the end of the list (a ';') 22754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // or an error, bail out. 22764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.isNot(tok::comma)) 22774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 22781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 22794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Consume the comma. 22801c94c16317c1a35c1549e022958188eea2567089Richard Smith SourceLocation CommaLoc = ConsumeToken(); 22811c94c16317c1a35c1549e022958188eea2567089Richard Smith 22821c94c16317c1a35c1549e022958188eea2567089Richard Smith if (Tok.isAtStartOfLine() && 22831c94c16317c1a35c1549e022958188eea2567089Richard Smith !MightBeDeclarator(Declarator::MemberContext)) { 22841c94c16317c1a35c1549e022958188eea2567089Richard Smith // This comma was followed by a line-break and something which can't be 22851c94c16317c1a35c1549e022958188eea2567089Richard Smith // the start of a declarator. The comma was probably a typo for a 22861c94c16317c1a35c1549e022958188eea2567089Richard Smith // semicolon. 22871c94c16317c1a35c1549e022958188eea2567089Richard Smith Diag(CommaLoc, diag::err_expected_semi_declaration) 22881c94c16317c1a35c1549e022958188eea2567089Richard Smith << FixItHint::CreateReplacement(CommaLoc, ";"); 22891c94c16317c1a35c1549e022958188eea2567089Richard Smith ExpectSemi = false; 22901c94c16317c1a35c1549e022958188eea2567089Richard Smith break; 22911c94c16317c1a35c1549e022958188eea2567089Richard Smith } 22921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 22934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the next declarator. 22944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclaratorInfo.clear(); 22954867347e82648d3baf09524b98b09c297a5a198fNico Weber VS.clear(); 2296147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor BitfieldSize = true; 2297a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor Init = true; 2298a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor HasInitializer = false; 22997984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith DeclaratorInfo.setCommaLoc(CommaLoc); 23001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2301ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling // Attributes are only allowed on the second declarator. 23027f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseGNUAttributes(DeclaratorInfo); 23034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 23043a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.isNot(tok::colon)) 23053a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 23064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 23074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 23081c94c16317c1a35c1549e022958188eea2567089Richard Smith if (ExpectSemi && 23091c94c16317c1a35c1549e022958188eea2567089Richard Smith ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) { 2310ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner // Skip to end of block or statement. 2311ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner SkipUntil(tok::r_brace, true, true); 2312ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner // If we stopped at a ';', eat it. 2313ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner if (Tok.is(tok::semi)) ConsumeToken(); 2314682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 23154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 23164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 231723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup.data(), 2318ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner DeclsInGroup.size()); 23194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 23204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 23217a614d8380297fcd2bc23986241905d97222948cRichard Smith/// ParseCXXMemberInitializer - Parse the brace-or-equal-initializer or 23227a614d8380297fcd2bc23986241905d97222948cRichard Smith/// pure-specifier. Also detect and reject any attempted defaulted/deleted 23237a614d8380297fcd2bc23986241905d97222948cRichard Smith/// function definition. The location of the '=', if any, will be placed in 23247a614d8380297fcd2bc23986241905d97222948cRichard Smith/// EqualLoc. 23257a614d8380297fcd2bc23986241905d97222948cRichard Smith/// 23267a614d8380297fcd2bc23986241905d97222948cRichard Smith/// pure-specifier: 23277a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '= 0' 232833deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// 23297a614d8380297fcd2bc23986241905d97222948cRichard Smith/// brace-or-equal-initializer: 23307a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '=' initializer-expression 233133deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// braced-init-list 233233deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// 23337a614d8380297fcd2bc23986241905d97222948cRichard Smith/// initializer-clause: 23347a614d8380297fcd2bc23986241905d97222948cRichard Smith/// assignment-expression 233533deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// braced-init-list 233633deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// 23377a614d8380297fcd2bc23986241905d97222948cRichard Smith/// defaulted/deleted function-definition: 23387a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '=' 'default' 23397a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '=' 'delete' 23407a614d8380297fcd2bc23986241905d97222948cRichard Smith/// 23417a614d8380297fcd2bc23986241905d97222948cRichard Smith/// Prior to C++0x, the assignment-expression in an initializer-clause must 23427a614d8380297fcd2bc23986241905d97222948cRichard Smith/// be a constant-expression. 2343552e29985a710f4ced62b39d70557501bd31ca9bDouglas GregorExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction, 23447a614d8380297fcd2bc23986241905d97222948cRichard Smith SourceLocation &EqualLoc) { 23457a614d8380297fcd2bc23986241905d97222948cRichard Smith assert((Tok.is(tok::equal) || Tok.is(tok::l_brace)) 23467a614d8380297fcd2bc23986241905d97222948cRichard Smith && "Data member initializer not starting with '=' or '{'"); 23477a614d8380297fcd2bc23986241905d97222948cRichard Smith 2348552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor EnterExpressionEvaluationContext Context(Actions, 2349552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor Sema::PotentiallyEvaluated, 2350552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor D); 23517a614d8380297fcd2bc23986241905d97222948cRichard Smith if (Tok.is(tok::equal)) { 23527a614d8380297fcd2bc23986241905d97222948cRichard Smith EqualLoc = ConsumeToken(); 23537a614d8380297fcd2bc23986241905d97222948cRichard Smith if (Tok.is(tok::kw_delete)) { 23547a614d8380297fcd2bc23986241905d97222948cRichard Smith // In principle, an initializer of '= delete p;' is legal, but it will 23557a614d8380297fcd2bc23986241905d97222948cRichard Smith // never type-check. It's better to diagnose it as an ill-formed expression 23567a614d8380297fcd2bc23986241905d97222948cRichard Smith // than as an ill-formed deleted non-function member. 23577a614d8380297fcd2bc23986241905d97222948cRichard Smith // An initializer of '= delete p, foo' will never be parsed, because 23587a614d8380297fcd2bc23986241905d97222948cRichard Smith // a top-level comma always ends the initializer expression. 23597a614d8380297fcd2bc23986241905d97222948cRichard Smith const Token &Next = NextToken(); 23607a614d8380297fcd2bc23986241905d97222948cRichard Smith if (IsFunction || Next.is(tok::semi) || Next.is(tok::comma) || 23617a614d8380297fcd2bc23986241905d97222948cRichard Smith Next.is(tok::eof)) { 23627a614d8380297fcd2bc23986241905d97222948cRichard Smith if (IsFunction) 23637a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) 23647a614d8380297fcd2bc23986241905d97222948cRichard Smith << 1 /* delete */; 23657a614d8380297fcd2bc23986241905d97222948cRichard Smith else 23667a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(ConsumeToken(), diag::err_deleted_non_function); 23677a614d8380297fcd2bc23986241905d97222948cRichard Smith return ExprResult(); 23687a614d8380297fcd2bc23986241905d97222948cRichard Smith } 23697a614d8380297fcd2bc23986241905d97222948cRichard Smith } else if (Tok.is(tok::kw_default)) { 23707a614d8380297fcd2bc23986241905d97222948cRichard Smith if (IsFunction) 23717a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(Tok, diag::err_default_delete_in_multiple_declaration) 23727a614d8380297fcd2bc23986241905d97222948cRichard Smith << 0 /* default */; 23737a614d8380297fcd2bc23986241905d97222948cRichard Smith else 23747a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(ConsumeToken(), diag::err_default_special_members); 23757a614d8380297fcd2bc23986241905d97222948cRichard Smith return ExprResult(); 23767a614d8380297fcd2bc23986241905d97222948cRichard Smith } 23777a614d8380297fcd2bc23986241905d97222948cRichard Smith 237833deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl } 237933deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl return ParseInitializer(); 23807a614d8380297fcd2bc23986241905d97222948cRichard Smith} 23817a614d8380297fcd2bc23986241905d97222948cRichard Smith 23824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition. 23834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 23844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-specification: 23854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declaration member-specification[opt] 23864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// access-specifier ':' member-specification[opt] 23874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 238817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matosvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, 238907fc1ba7553f2f5bf26984091197311decd9028eMichael Han SourceLocation AttrFixitLoc, 2390053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith ParsedAttributesWithRange &Attrs, 239117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos unsigned TagType, Decl *TagDecl) { 239217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos assert((TagType == DeclSpec::TST_struct || 239317d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType == DeclSpec::TST_interface || 239417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType == DeclSpec::TST_union || 239517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType == DeclSpec::TST_class) && "Invalid TagType!"); 239617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos 2397f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc, 2398f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall "parsing struct/union/class body"); 23991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 240026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // Determine whether this is a non-nested class. Note that local 240126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // classes are *not* considered to be nested classes. 240226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor bool NonNestedClass = true; 240326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (!ClassStack.empty()) { 240423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor for (const Scope *S = getCurScope(); S; S = S->getParent()) { 240526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (S->isClassScope()) { 240626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // We're inside a class scope, so this is a nested class. 240726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor NonNestedClass = false; 2408e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall 2409e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall // The Microsoft extension __interface does not permit nested classes. 2410e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall if (getCurrentClass().IsInterface) { 2411e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall Diag(RecordLoc, diag::err_invalid_member_in_interface) 2412e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall << /*ErrorType=*/6 2413e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall << (isa<NamedDecl>(TagDecl) 2414e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall ? cast<NamedDecl>(TagDecl)->getQualifiedNameAsString() 2415e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall : "<anonymous>"); 2416e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall } 241726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor break; 241826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 241926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor 242026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if ((S->getFlags() & Scope::FnScope)) { 242126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // If we're in a function or function template declared in the 242226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // body of a class, then this is a local class rather than a 242326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // nested class. 242426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor const Scope *Parent = S->getParent(); 242526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (Parent->isTemplateParamScope()) 242626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor Parent = Parent->getParent(); 242726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (Parent->isClassScope()) 242826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor break; 242926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 243026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 243126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 24324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 24334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Enter a scope for the class. 24343218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope); 24354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 24366569d68745c8213709740337d2be52b031384f58Douglas Gregor // Note that we are parsing a new (potentially-nested) class definition. 2437e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass, 2438e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall TagType == DeclSpec::TST_interface); 24396569d68745c8213709740337d2be52b031384f58Douglas Gregor 2440ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor if (TagDecl) 244123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); 2442bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 2443b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson SourceLocation FinalLoc; 2444b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson 2445b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson // Parse the optional 'final' keyword. 24464e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) { 24474e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith assert(isCXX11FinalKeyword() && "not a class definition"); 24488b11b5e6ce086fcaa7344bf84cffefcf4b53f9f6Richard Smith FinalLoc = ConsumeToken(); 2449b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson 2450e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall if (TagType == DeclSpec::TST_interface) { 2451e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall Diag(FinalLoc, diag::err_override_control_interface) 2452e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall << "final"; 2453e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall } else { 245480ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith Diag(FinalLoc, getLangOpts().CPlusPlus11 ? 2455e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall diag::warn_cxx98_compat_override_control_keyword : 2456e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall diag::ext_override_control_keyword) << "final"; 2457e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall } 24582e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 245907fc1ba7553f2f5bf26984091197311decd9028eMichael Han // Parse any C++11 attributes after 'final' keyword. 246007fc1ba7553f2f5bf26984091197311decd9028eMichael Han // These attributes are not allowed to appear here, 246107fc1ba7553f2f5bf26984091197311decd9028eMichael Han // and the only possible place for them to appertain 246207fc1ba7553f2f5bf26984091197311decd9028eMichael Han // to the class would be between class-key and class-name. 2463053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc); 2464b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson } 2465cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 2466bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall if (Tok.is(tok::colon)) { 2467bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall ParseBaseClause(TagDecl); 2468bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 2469bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall if (!Tok.is(tok::l_brace)) { 2470bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall Diag(Tok, diag::err_expected_lbrace_after_base_specifiers); 2471db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall 2472db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall if (TagDecl) 247323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnTagDefinitionError(getCurScope(), TagDecl); 2474bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall return; 2475bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall } 2476bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall } 2477bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 2478bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall assert(Tok.is(tok::l_brace)); 24794a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_brace); 24804a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 2481bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 248242a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall if (TagDecl) 24832c3ee54e51d835a35bbf781c69e17f39e2ba0480Anders Carlsson Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc, 24844a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getOpenLocation()); 2485f9368159334ff86ea5fa367225c1a580977f3b03John McCall 24864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // C++ 11p3: Members of a class defined with the keyword class are private 24874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // by default. Members of a class defined with the keywords struct or union 24884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // are public by default. 24894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AccessSpecifier CurAS; 24904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (TagType == DeclSpec::TST_class) 24914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS_private; 24924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis else 24934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS_public; 24945f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParsedAttributes AccessAttrs(AttrFactory); 24954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 249607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (TagDecl) { 249707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // While we still have something to read, read the member-declarations. 249807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 249907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Each iteration of this loop reads one member-declaration. 250007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor 25014e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) || 2502563a645de82231a55e221fe655b7188bf8369662Francois Pichet Tok.is(tok::kw___if_not_exists))) { 2503563a645de82231a55e221fe655b7188bf8369662Francois Pichet ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS); 2504563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 2505563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 2506563a645de82231a55e221fe655b7188bf8369662Francois Pichet 250707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Check for extraneous top-level semicolon. 250807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (Tok.is(tok::semi)) { 2509eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith ConsumeExtraSemi(InsideStruct, TagType); 251007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor continue; 251107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } 25121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2513aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman if (Tok.is(tok::annot_pragma_vis)) { 2514aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman HandlePragmaVisibility(); 2515aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman continue; 2516aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman } 2517aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman 2518aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman if (Tok.is(tok::annot_pragma_pack)) { 2519aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman HandlePragmaPack(); 2520aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman continue; 2521aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman } 2522aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman 2523f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis if (Tok.is(tok::annot_pragma_align)) { 2524f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis HandlePragmaAlign(); 2525f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis continue; 2526f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis } 2527f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis 2528c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev if (Tok.is(tok::annot_pragma_openmp)) { 2529c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev ParseOpenMPDeclarativeDirective(); 2530c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev continue; 2531c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev } 2532c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev 253307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor AccessSpecifier AS = getAccessSpecifierIfPresent(); 253407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (AS != AS_none) { 253507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Current token is a C++ access specifier. 253607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor CurAS = AS; 253707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor SourceLocation ASLoc = Tok.getLocation(); 253813f8daf70637f8f295134ac8e089dd7721e09085David Blaikie unsigned TokLength = Tok.getLength(); 253907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor ConsumeToken(); 25405f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen AccessAttrs.clear(); 25415f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen MaybeParseGNUAttributes(AccessAttrs); 25425f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen 254313f8daf70637f8f295134ac8e089dd7721e09085David Blaikie SourceLocation EndLoc; 254413f8daf70637f8f295134ac8e089dd7721e09085David Blaikie if (Tok.is(tok::colon)) { 254513f8daf70637f8f295134ac8e089dd7721e09085David Blaikie EndLoc = Tok.getLocation(); 254613f8daf70637f8f295134ac8e089dd7721e09085David Blaikie ConsumeToken(); 254713f8daf70637f8f295134ac8e089dd7721e09085David Blaikie } else if (Tok.is(tok::semi)) { 254813f8daf70637f8f295134ac8e089dd7721e09085David Blaikie EndLoc = Tok.getLocation(); 254913f8daf70637f8f295134ac8e089dd7721e09085David Blaikie ConsumeToken(); 255013f8daf70637f8f295134ac8e089dd7721e09085David Blaikie Diag(EndLoc, diag::err_expected_colon) 255113f8daf70637f8f295134ac8e089dd7721e09085David Blaikie << FixItHint::CreateReplacement(EndLoc, ":"); 255213f8daf70637f8f295134ac8e089dd7721e09085David Blaikie } else { 255313f8daf70637f8f295134ac8e089dd7721e09085David Blaikie EndLoc = ASLoc.getLocWithOffset(TokLength); 255413f8daf70637f8f295134ac8e089dd7721e09085David Blaikie Diag(EndLoc, diag::err_expected_colon) 255513f8daf70637f8f295134ac8e089dd7721e09085David Blaikie << FixItHint::CreateInsertion(EndLoc, ":"); 255613f8daf70637f8f295134ac8e089dd7721e09085David Blaikie } 2557c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen 2558e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall // The Microsoft extension __interface does not permit non-public 2559e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall // access specifiers. 2560e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall if (TagType == DeclSpec::TST_interface && CurAS != AS_public) { 2561e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall Diag(ASLoc, diag::err_access_specifier_interface) 2562e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall << (CurAS == AS_protected); 2563e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall } 2564e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall 2565c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen if (Actions.ActOnAccessSpecifier(AS, ASLoc, EndLoc, 2566c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen AccessAttrs.getList())) { 2567c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen // found another attribute than only annotations 2568c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen AccessAttrs.clear(); 2569c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen } 2570c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen 257107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor continue; 257207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } 25734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 257407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // FIXME: Make sure we don't have a template here. 25754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 257607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Parse all the comma separated declarators. 25775f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParseCXXClassMemberDeclaration(CurAS, AccessAttrs.getList()); 257807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } 25791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 25804a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 258107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } else { 258207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor SkipUntil(tok::r_brace, false, false); 25834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 25841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 25854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If attributes exist after class contents, parse them. 25860b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributes attrs(AttrFactory); 25877f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseGNUAttributes(attrs); 25884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 258942a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall if (TagDecl) 259023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl, 25914a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getOpenLocation(), 25924a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation(), 25937f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall attrs.getList()); 25944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 259574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // C++11 [class.mem]p2: 259674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Within the class member-specification, the class is regarded as complete 2597a058fd4f0a944174295f77169b438510dad389f8Richard Smith // within function bodies, default arguments, and 259874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // brace-or-equal-initializers for non-static data members (including such 259974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // things in nested classes). 260007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (TagDecl && NonNestedClass) { 26014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // We are not inside a nested class. This class and its nested classes 260272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // are complete and we can parse the delayed portions of method 2603eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // declarations and the lexed inline method definitions, along with any 2604eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // delayed attributes. 2605e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor SourceLocation SavedPrevTokLocation = PrevTokLocation; 2606eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski ParseLexedAttributes(getCurrentClass()); 26076569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseLexedMethodDeclarations(getCurrentClass()); 2608a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith 2609a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith // We've finished with all pending member declarations. 2610a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith Actions.ActOnFinishCXXMemberDecls(); 2611a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith 26127a614d8380297fcd2bc23986241905d97222948cRichard Smith ParseLexedMemberInitializers(getCurrentClass()); 26136569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseLexedMethodDefs(getCurrentClass()); 2614e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor PrevTokLocation = SavedPrevTokLocation; 26154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 26164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 261742a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall if (TagDecl) 26184a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, 26194a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 2620db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall 26214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Leave the class scope. 26226569d68745c8213709740337d2be52b031384f58Douglas Gregor ParsingDef.Pop(); 26238935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ClassScope.Exit(); 26244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 26257ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 26267ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer, 26277ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a 26287ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers 26297ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below: 26307ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 26317ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code 26327ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { }; 26337ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base { 26347ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// int x; 26357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// float f; 26367ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public: 26377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// Derived(float f) : Base(), x(17), f(f) { } 26387ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// }; 26397ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode 26407ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 26411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++] ctor-initializer: 26421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ':' mem-initializer-list 26437ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 26441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++] mem-initializer-list: 26453fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor/// mem-initializer ...[opt] 26463fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor/// mem-initializer ...[opt] , mem-initializer-list 2647d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseConstructorInitializer(Decl *ConstructorDecl) { 26487ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'"); 26497ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 265028bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley // Poison the SEH identifiers so they are flagged as illegal in constructor initializers 265128bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true); 26527ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation ColonLoc = ConsumeToken(); 26531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CXXCtorInitializer*, 4> MemInitializers; 26559db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor bool AnyErrors = false; 2656193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 26577ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor do { 26580133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor if (Tok.is(tok::code_completion)) { 26590133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor Actions.CodeCompleteConstructorInitializer(ConstructorDecl, 26600133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor MemInitializers.data(), 26610133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor MemInitializers.size()); 26627d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return cutOffParsing(); 26630133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor } else { 26640133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); 26650133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor if (!MemInit.isInvalid()) 26660133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor MemInitializers.push_back(MemInit.get()); 26670133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor else 26680133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor AnyErrors = true; 26690133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor } 26700133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor 26717ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.is(tok::comma)) 26727ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor ConsumeToken(); 26737ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor else if (Tok.is(tok::l_brace)) 26747ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor break; 2675b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor // If the next token looks like a base or member initializer, assume that 2676b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor // we're just missing a comma. 2677751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor else if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) { 2678751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation); 2679751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor Diag(Loc, diag::err_ctor_init_missing_comma) 2680751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor << FixItHint::CreateInsertion(Loc, ", "); 2681751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor } else { 26827ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Skip over garbage, until we get to '{'. Don't eat the '{'. 2683d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma); 26847ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SkipUntil(tok::l_brace, true, true); 26857ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor break; 26867ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 26877ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } while (true); 26887ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 268993c8617bec98aeb769ee9f569d7ed439eec03249David Blaikie Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, MemInitializers, 26909db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor AnyErrors); 26917ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor} 26927ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 26937ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is 26947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one 26957ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See 26967ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example. 26977ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 26987ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer: 26997ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// mem-initializer-id '(' expression-list[opt] ')' 2700dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// [C++0x] mem-initializer-id braced-init-list 27011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 27027ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id: 27037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// '::'[opt] nested-name-specifier[opt] class-name 27047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// identifier 2705d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) { 2706bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian // parse '::'[opt] nested-name-specifier[opt] 2707bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian CXXScopeSpec SS; 2708efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 2709b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TemplateTypeTy; 2710961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian if (Tok.is(tok::annot_template_id)) { 271125a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 2712d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor if (TemplateId->Kind == TNK_Type_template || 2713d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor TemplateId->Kind == TNK_Dependent_template_name) { 2714059101f922de6eb765601459925f4c8914420b23Douglas Gregor AnnotateTemplateIdTokenAsType(); 2715961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); 2716b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall TemplateTypeTy = getTypeAnnotation(Tok); 2717961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian } 2718961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian } 2719f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // Uses of decltype will already have been converted to annot_decltype by 2720f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // ParseOptionalCXXScopeSpecifier at this point. 2721f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie if (!TemplateTypeTy && Tok.isNot(tok::identifier) 2722f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie && Tok.isNot(tok::annot_decltype)) { 27231ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_member_or_base_name); 27247ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor return true; 27257ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 27261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2727f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie IdentifierInfo *II = 0; 2728f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie DeclSpec DS(AttrFactory); 2729f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie SourceLocation IdLoc = Tok.getLocation(); 2730f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie if (Tok.is(tok::annot_decltype)) { 2731f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // Get the decltype expression, if there is one. 2732f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie ParseDecltypeSpecifier(DS); 2733f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie } else { 2734f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie if (Tok.is(tok::identifier)) 2735f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // Get the identifier. This may be a member name or a class name, 2736f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // but we'll let the semantic analysis determine which it is. 2737f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie II = Tok.getIdentifierInfo(); 2738f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie ConsumeToken(); 2739f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie } 2740f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie 27417ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 27427ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Parse the '('. 274380ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 27447fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 27457fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 27466df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl ExprResult InitList = ParseBraceInitializer(); 27476df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl if (InitList.isInvalid()) 27486df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl return true; 27496df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl 27506df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl SourceLocation EllipsisLoc; 27516df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl if (Tok.is(tok::ellipsis)) 27526df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl EllipsisLoc = ConsumeToken(); 27536df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl 27546df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II, 2755f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie TemplateTypeTy, DS, IdLoc, 2756f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie InitList.take(), EllipsisLoc); 2757dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } else if(Tok.is(tok::l_paren)) { 27584a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 27594a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 2760dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl 2761dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl // Parse the optional expression-list. 27624e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer ExprVector ArgExprs; 2763dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl CommaLocsTy CommaLocs; 2764dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) { 2765dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl SkipUntil(tok::r_paren); 2766dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return true; 2767dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } 27687ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 27694a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 27707ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 2771dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl SourceLocation EllipsisLoc; 2772dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (Tok.is(tok::ellipsis)) 2773dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl EllipsisLoc = ConsumeToken(); 27747ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 2775dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II, 2776f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie TemplateTypeTy, DS, IdLoc, 27774e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer T.getOpenLocation(), ArgExprs.data(), 27784a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor ArgExprs.size(), T.getCloseLocation(), 2779dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl EllipsisLoc); 2780dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } 2781dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl 278280ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith Diag(Tok, getLangOpts().CPlusPlus11 ? diag::err_expected_lparen_or_lbrace 2783dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl : diag::err_expected_lparen); 2784dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return true; 27857ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor} 27860fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 27877acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// \brief Parse a C++ exception-specification if present (C++0x [except.spec]). 27880fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 2789a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// exception-specification: 27907acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification 27917acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// noexcept-specification 27927acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 27937acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// noexcept-specification: 27947acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 'noexcept' 27957acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 'noexcept' '(' constant-expression ')' 27967acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType 2797a058fd4f0a944174295f77169b438510dad389f8Richard SmithParser::tryParseExceptionSpecification( 279874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor SourceRange &SpecificationRange, 27995f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<ParsedType> &DynamicExceptions, 28005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<SourceRange> &DynamicExceptionRanges, 2801a058fd4f0a944174295f77169b438510dad389f8Richard Smith ExprResult &NoexceptExpr) { 28027acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl ExceptionSpecificationType Result = EST_None; 2803a058fd4f0a944174295f77169b438510dad389f8Richard Smith 28047acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // See if there's a dynamic specification. 28057acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.is(tok::kw_throw)) { 28067acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Result = ParseDynamicExceptionSpecification(SpecificationRange, 28077acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl DynamicExceptions, 28087acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl DynamicExceptionRanges); 28097acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl assert(DynamicExceptions.size() == DynamicExceptionRanges.size() && 28107acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl "Produced different number of exception types and ranges."); 28117acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 28127acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 28137acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // If there's no noexcept specification, we're done. 28147acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.isNot(tok::kw_noexcept)) 28157acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl return Result; 28167acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 2817841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith Diag(Tok, diag::warn_cxx98_compat_noexcept_decl); 2818841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith 28197acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // If we already had a dynamic specification, parse the noexcept for, 28207acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // recovery, but emit a diagnostic and don't store the results. 28217acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SourceRange NoexceptRange; 28227acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl ExceptionSpecificationType NoexceptType = EST_None; 28237acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 28247acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SourceLocation KeywordLoc = ConsumeToken(); 28257acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.is(tok::l_paren)) { 28267acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // There is an argument. 28274a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 28284a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 28297acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptType = EST_ComputedNoexcept; 28307acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptExpr = ParseConstantExpression(); 283160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // The argument must be contextually convertible to bool. We use 283260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // ActOnBooleanCondition for this purpose. 283360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (!NoexceptExpr.isInvalid()) 283460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NoexceptExpr = Actions.ActOnBooleanCondition(getCurScope(), KeywordLoc, 283560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NoexceptExpr.get()); 28364a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 28374a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation()); 28387acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } else { 28397acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // There is no argument. 28407acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptType = EST_BasicNoexcept; 28417acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptRange = SourceRange(KeywordLoc, KeywordLoc); 28427acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 28437acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 28447acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Result == EST_None) { 28457acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SpecificationRange = NoexceptRange; 28467acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Result = NoexceptType; 28477acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 28487acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // If there's a dynamic specification after a noexcept specification, 28497acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // parse that and ignore the results. 28507acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.is(tok::kw_throw)) { 28517acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification); 28527acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions, 28537acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl DynamicExceptionRanges); 28547acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 28557acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } else { 28567acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification); 28577acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 28587acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 28597acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl return Result; 28607acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl} 28617acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 28627acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// ParseDynamicExceptionSpecification - Parse a C++ 28637acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification (C++ [except.spec]). 28647acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 28657acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification: 2866a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// 'throw' '(' type-id-list [opt] ')' 2867a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS] 'throw' '(' '...' ')' 28681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 2869a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// type-id-list: 2870a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor/// type-id ... [opt] 2871a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor/// type-id-list ',' type-id ... [opt] 28720fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 28737acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType Parser::ParseDynamicExceptionSpecification( 28747acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SourceRange &SpecificationRange, 28755f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<ParsedType> &Exceptions, 28765f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<SourceRange> &Ranges) { 28770fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor assert(Tok.is(tok::kw_throw) && "expected throw"); 28781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 28797acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SpecificationRange.setBegin(ConsumeToken()); 28804a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 28814a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.consumeOpen()) { 28827acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Diag(Tok, diag::err_expected_lparen_after) << "throw"; 28837acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SpecificationRange.setEnd(SpecificationRange.getBegin()); 288460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return EST_DynamicNone; 28850fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor } 28860fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 2887a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor // Parse throw(...), a Microsoft extension that means "this function 2888a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor // can throw anything". 2889a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor if (Tok.is(tok::ellipsis)) { 2890a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor SourceLocation EllipsisLoc = ConsumeToken(); 28914e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().MicrosoftExt) 2892a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec); 28934a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 28944a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SpecificationRange.setEnd(T.getCloseLocation()); 289560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return EST_MSAny; 2896a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor } 2897a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor 28980fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor // Parse the sequence of type-ids. 2899ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl SourceRange Range; 29000fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor while (Tok.isNot(tok::r_paren)) { 2901ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl TypeResult Res(ParseTypeName(&Range)); 29027acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 2903a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor if (Tok.is(tok::ellipsis)) { 2904a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor // C++0x [temp.variadic]p5: 2905a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor // - In a dynamic-exception-specification (15.4); the pattern is a 2906a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor // type-id. 2907a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor SourceLocation Ellipsis = ConsumeToken(); 29087acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Range.setEnd(Ellipsis); 2909a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor if (!Res.isInvalid()) 2910a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor Res = Actions.ActOnPackExpansion(Res.get(), Ellipsis); 2911a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor } 29127acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 2913ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl if (!Res.isInvalid()) { 29147dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl Exceptions.push_back(Res.get()); 2915ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl Ranges.push_back(Range); 2916ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl } 2917a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor 29180fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor if (Tok.is(tok::comma)) 29190fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor ConsumeToken(); 29207dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl else 29210fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor break; 29220fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor } 29230fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 29244a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 29254a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SpecificationRange.setEnd(T.getCloseLocation()); 292660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic; 29270fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor} 29286569d68745c8213709740337d2be52b031384f58Douglas Gregor 2929dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// ParseTrailingReturnType - Parse a trailing return type on a new-style 2930dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// function declaration. 2931ae7902c4293d9de8b9591759513f0d075f45022aDouglas GregorTypeResult Parser::ParseTrailingReturnType(SourceRange &Range) { 2932dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor assert(Tok.is(tok::arrow) && "expected arrow"); 2933dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor 2934dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor ConsumeToken(); 2935dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor 29367796eb5643244f3134834253ce5ea89107ac21c1Richard Smith return ParseTypeName(&Range, Declarator::TrailingReturnContext); 2937dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor} 2938dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor 29396569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief We have just started parsing the definition of a new class, 29406569d68745c8213709740337d2be52b031384f58Douglas Gregor/// so push that class onto our stack of classes that is currently 29416569d68745c8213709740337d2be52b031384f58Douglas Gregor/// being parsed. 2942eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallSema::ParsingClassState 2943e402e72273cde2a64fa6097c1fe93f500038675dJohn McCallParser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass, 2944e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall bool IsInterface) { 294526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor assert((NonNestedClass || !ClassStack.empty()) && 29466569d68745c8213709740337d2be52b031384f58Douglas Gregor "Nested class without outer class"); 2947e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass, IsInterface)); 2948eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall return Actions.PushParsingClass(); 29496569d68745c8213709740337d2be52b031384f58Douglas Gregor} 29506569d68745c8213709740337d2be52b031384f58Douglas Gregor 29516569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Deallocate the given parsed class and all of its nested 29526569d68745c8213709740337d2be52b031384f58Douglas Gregor/// classes. 29536569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) { 2954d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I) 2955d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor delete Class->LateParsedDeclarations[I]; 29566569d68745c8213709740337d2be52b031384f58Douglas Gregor delete Class; 29576569d68745c8213709740337d2be52b031384f58Douglas Gregor} 29586569d68745c8213709740337d2be52b031384f58Douglas Gregor 29596569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Pop the top class of the stack of classes that are 29606569d68745c8213709740337d2be52b031384f58Douglas Gregor/// currently being parsed. 29616569d68745c8213709740337d2be52b031384f58Douglas Gregor/// 29626569d68745c8213709740337d2be52b031384f58Douglas Gregor/// This routine should be called when we have finished parsing the 29636569d68745c8213709740337d2be52b031384f58Douglas Gregor/// definition of a class, but have not yet popped the Scope 29646569d68745c8213709740337d2be52b031384f58Douglas Gregor/// associated with the class's definition. 2965eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Parser::PopParsingClass(Sema::ParsingClassState state) { 29666569d68745c8213709740337d2be52b031384f58Douglas Gregor assert(!ClassStack.empty() && "Mismatched push/pop for class parsing"); 29671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2968eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall Actions.PopParsingClass(state); 2969eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 29706569d68745c8213709740337d2be52b031384f58Douglas Gregor ParsingClass *Victim = ClassStack.top(); 29716569d68745c8213709740337d2be52b031384f58Douglas Gregor ClassStack.pop(); 29726569d68745c8213709740337d2be52b031384f58Douglas Gregor if (Victim->TopLevelClass) { 29736569d68745c8213709740337d2be52b031384f58Douglas Gregor // Deallocate all of the nested classes of this class, 29746569d68745c8213709740337d2be52b031384f58Douglas Gregor // recursively: we don't need to keep any of this information. 29756569d68745c8213709740337d2be52b031384f58Douglas Gregor DeallocateParsedClasses(Victim); 29766569d68745c8213709740337d2be52b031384f58Douglas Gregor return; 29771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 29786569d68745c8213709740337d2be52b031384f58Douglas Gregor assert(!ClassStack.empty() && "Missing top-level class?"); 29796569d68745c8213709740337d2be52b031384f58Douglas Gregor 2980d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (Victim->LateParsedDeclarations.empty()) { 29816569d68745c8213709740337d2be52b031384f58Douglas Gregor // The victim is a nested class, but we will not need to perform 29826569d68745c8213709740337d2be52b031384f58Douglas Gregor // any processing after the definition of this class since it has 29836569d68745c8213709740337d2be52b031384f58Douglas Gregor // no members whose handling was delayed. Therefore, we can just 29846569d68745c8213709740337d2be52b031384f58Douglas Gregor // remove this nested class. 2985d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor DeallocateParsedClasses(Victim); 29866569d68745c8213709740337d2be52b031384f58Douglas Gregor return; 29876569d68745c8213709740337d2be52b031384f58Douglas Gregor } 29886569d68745c8213709740337d2be52b031384f58Douglas Gregor 29896569d68745c8213709740337d2be52b031384f58Douglas Gregor // This nested class has some members that will need to be processed 29906569d68745c8213709740337d2be52b031384f58Douglas Gregor // after the top-level class is completely defined. Therefore, add 29916569d68745c8213709740337d2be52b031384f58Douglas Gregor // it to the list of nested classes within its parent. 299223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor assert(getCurScope()->isClassScope() && "Nested class outside of class scope?"); 2993d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ClassStack.top()->LateParsedDeclarations.push_back(new LateParsedClass(this, Victim)); 299423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope(); 29956569d68745c8213709740337d2be52b031384f58Douglas Gregor} 2996bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 2997c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// \brief Try to parse an 'identifier' which appears within an attribute-token. 2998c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// 2999c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// \return the parsed identifier on success, and 0 if the next token is not an 3000c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute-token. 3001c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// 3002c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// C++11 [dcl.attr.grammar]p3: 3003c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// If a keyword or an alternative token that satisfies the syntactic 3004c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// requirements of an identifier is contained in an attribute-token, 3005c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// it is considered an identifier. 3006c56298d87a9df507805a548d7d515e8b511df2c0Richard SmithIdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(SourceLocation &Loc) { 3007c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith switch (Tok.getKind()) { 3008c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith default: 3009c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // Identifiers and keywords have identifier info attached. 3010c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (IdentifierInfo *II = Tok.getIdentifierInfo()) { 3011c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith Loc = ConsumeToken(); 3012c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith return II; 3013c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 3014c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith return 0; 3015c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 3016c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::ampamp: // 'and' 3017c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::pipe: // 'bitor' 3018c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::pipepipe: // 'or' 3019c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::caret: // 'xor' 3020c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::tilde: // 'compl' 3021c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::amp: // 'bitand' 3022c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::ampequal: // 'and_eq' 3023c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::pipeequal: // 'or_eq' 3024c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::caretequal: // 'xor_eq' 3025c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::exclaim: // 'not' 3026c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::exclaimequal: // 'not_eq' 3027c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // Alternative tokens do not have identifier info, but their spelling 3028c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // starts with an alphabetical character. 3029cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallString<8> SpellingBuf; 3030c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith StringRef Spelling = PP.getSpelling(Tok.getLocation(), SpellingBuf); 30313f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose if (isLetter(Spelling[0])) { 3032c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith Loc = ConsumeToken(); 30330eb7526cd2524af78fb9a2a2522045fb25fc3d27Benjamin Kramer return &PP.getIdentifierTable().get(Spelling); 3034c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 3035c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith return 0; 3036c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 3037c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith} 3038c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 30396880f492365cc4fa4c941aa83688635003ee7498Michael Hanstatic bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName, 30406880f492365cc4fa4c941aa83688635003ee7498Michael Han IdentifierInfo *ScopeName) { 30416880f492365cc4fa4c941aa83688635003ee7498Michael Han switch (AttributeList::getKind(AttrName, ScopeName, 30426880f492365cc4fa4c941aa83688635003ee7498Michael Han AttributeList::AS_CXX11)) { 30436880f492365cc4fa4c941aa83688635003ee7498Michael Han case AttributeList::AT_CarriesDependency: 30446880f492365cc4fa4c941aa83688635003ee7498Michael Han case AttributeList::AT_FallThrough: 3045cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith case AttributeList::AT_CXX11NoReturn: { 30466880f492365cc4fa4c941aa83688635003ee7498Michael Han return true; 30476880f492365cc4fa4c941aa83688635003ee7498Michael Han } 30486880f492365cc4fa4c941aa83688635003ee7498Michael Han 30496880f492365cc4fa4c941aa83688635003ee7498Michael Han default: 30506880f492365cc4fa4c941aa83688635003ee7498Michael Han return false; 30516880f492365cc4fa4c941aa83688635003ee7498Michael Han } 30526880f492365cc4fa4c941aa83688635003ee7498Michael Han} 30536880f492365cc4fa4c941aa83688635003ee7498Michael Han 3054c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier. Currently 30553497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// only parses standard attributes. 3056bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 30576ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-specifier: 3058bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '[' '[' attribute-list ']' ']' 305982d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne/// alignment-specifier 3060bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 30616ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-list: 3062bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute[opt] 3063bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-list ',' attribute[opt] 3064c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute '...' 3065c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute-list ',' attribute '...' 3066bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 30676ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute: 3068bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-token attribute-argument-clause[opt] 3069bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 30706ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-token: 3071bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// identifier 3072bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-scoped-token 3073bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 30746ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-scoped-token: 3075bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-namespace '::' identifier 3076bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 30776ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-namespace: 3078bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// identifier 3079bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 30806ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-argument-clause: 3081bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '(' balanced-token-seq ')' 3082bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 30836ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] balanced-token-seq: 3084bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// balanced-token 3085bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// balanced-token-seq balanced-token 3086bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 30876ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] balanced-token: 3088bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '(' balanced-token-seq ')' 3089bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '[' balanced-token-seq ']' 3090bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '{' balanced-token-seq '}' 3091bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// any token but '(', ')', '[', ']', '{', or '}' 3092c56298d87a9df507805a548d7d515e8b511df2c0Richard Smithvoid Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs, 30933497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne SourceLocation *endLoc) { 309482d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne if (Tok.is(tok::kw_alignas)) { 309541be673e93ed225b45479557b20ff19b3082bae8Richard Smith Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas); 309682d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne ParseAlignmentSpecifier(attrs, endLoc); 309782d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne return; 309882d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne } 309982d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne 3100bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square) 31016ee326af4e77e6f05973486097884d7431f2108dRichard Smith && "Not a C++11 attribute list"); 3102bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 310341be673e93ed225b45479557b20ff19b3082bae8Richard Smith Diag(Tok.getLocation(), diag::warn_cxx98_compat_attribute); 310441be673e93ed225b45479557b20ff19b3082bae8Richard Smith 3105bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeBracket(); 3106bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeBracket(); 3107193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 3108cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith llvm::SmallDenseMap<IdentifierInfo*, SourceLocation, 4> SeenAttrs; 3109cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith 3110c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith while (Tok.isNot(tok::r_square)) { 3111bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // attribute not present 3112bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.is(tok::comma)) { 3113bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeToken(); 3114bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt continue; 3115bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 3116bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 3117c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith SourceLocation ScopeLoc, AttrLoc; 3118c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith IdentifierInfo *ScopeName = 0, *AttrName = 0; 3119c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 3120c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith AttrName = TryParseCXX11AttributeIdentifier(AttrLoc); 3121c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (!AttrName) 3122c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // Break out to the "expected ']'" diagnostic. 3123c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith break; 3124193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 3125bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // scoped attribute 3126bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.is(tok::coloncolon)) { 3127bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeToken(); 3128bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 3129c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith ScopeName = AttrName; 3130c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith ScopeLoc = AttrLoc; 3131c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 3132c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith AttrName = TryParseCXX11AttributeIdentifier(AttrLoc); 3133c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (!AttrName) { 3134bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt Diag(Tok.getLocation(), diag::err_expected_ident); 3135bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_square, tok::comma, true, true); 3136bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt continue; 3137bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 3138bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 3139bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 31406880f492365cc4fa4c941aa83688635003ee7498Michael Han bool StandardAttr = IsBuiltInOrStandardCXX11Attribute(AttrName,ScopeName); 3141bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt bool AttrParsed = false; 31426880f492365cc4fa4c941aa83688635003ee7498Michael Han 3143cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith if (StandardAttr && 3144cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith !SeenAttrs.insert(std::make_pair(AttrName, AttrLoc)).second) 3145cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith Diag(AttrLoc, diag::err_cxx11_attribute_repeated) 3146cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith << AttrName << SourceRange(SeenAttrs[AttrName]); 3147cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith 31486880f492365cc4fa4c941aa83688635003ee7498Michael Han // Parse attribute arguments 31496880f492365cc4fa4c941aa83688635003ee7498Michael Han if (Tok.is(tok::l_paren)) { 31506880f492365cc4fa4c941aa83688635003ee7498Michael Han if (ScopeName && ScopeName->getName() == "gnu") { 31516880f492365cc4fa4c941aa83688635003ee7498Michael Han ParseGNUAttributeArgs(AttrName, AttrLoc, attrs, endLoc, 31526880f492365cc4fa4c941aa83688635003ee7498Michael Han ScopeName, ScopeLoc, AttributeList::AS_CXX11); 31536880f492365cc4fa4c941aa83688635003ee7498Michael Han AttrParsed = true; 31546880f492365cc4fa4c941aa83688635003ee7498Michael Han } else { 31556880f492365cc4fa4c941aa83688635003ee7498Michael Han if (StandardAttr) 31566880f492365cc4fa4c941aa83688635003ee7498Michael Han Diag(Tok.getLocation(), diag::err_cxx11_attribute_forbids_arguments) 31576880f492365cc4fa4c941aa83688635003ee7498Michael Han << AttrName->getName(); 31586880f492365cc4fa4c941aa83688635003ee7498Michael Han 31596880f492365cc4fa4c941aa83688635003ee7498Michael Han // FIXME: handle other formats of c++11 attribute arguments 31606880f492365cc4fa4c941aa83688635003ee7498Michael Han ConsumeParen(); 31616880f492365cc4fa4c941aa83688635003ee7498Michael Han SkipUntil(tok::r_paren, false); 3162bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 31636880f492365cc4fa4c941aa83688635003ee7498Michael Han } 3164bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 31656880f492365cc4fa4c941aa83688635003ee7498Michael Han if (!AttrParsed) 3166e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith attrs.addNew(AttrName, 3167e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, 3168e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith AttrLoc), 3169e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith ScopeName, ScopeLoc, 0, 317093f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt SourceLocation(), 0, 0, AttributeList::AS_CXX11); 31716ee326af4e77e6f05973486097884d7431f2108dRichard Smith 3172c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (Tok.is(tok::ellipsis)) { 31736ee326af4e77e6f05973486097884d7431f2108dRichard Smith ConsumeToken(); 31746880f492365cc4fa4c941aa83688635003ee7498Michael Han 31756880f492365cc4fa4c941aa83688635003ee7498Michael Han Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) 31766880f492365cc4fa4c941aa83688635003ee7498Michael Han << AttrName->getName(); 3177c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 3178bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 3179bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 3180bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare)) 3181bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_square, false); 31823497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne if (endLoc) 31833497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne *endLoc = Tok.getLocation(); 3184bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare)) 3185bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_square, false); 31863497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne} 31873497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne 31882edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt/// ParseCXX11Attributes - Parse a C++11 attribute-specifier-seq. 31893497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// 31903497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// attribute-specifier-seq: 31913497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// attribute-specifier-seq[opt] attribute-specifier 3192c56298d87a9df507805a548d7d515e8b511df2c0Richard Smithvoid Parser::ParseCXX11Attributes(ParsedAttributesWithRange &attrs, 31933497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne SourceLocation *endLoc) { 3194672edb0a04a5273e3a501f3b196844c125290780Richard Smith assert(getLangOpts().CPlusPlus11); 3195672edb0a04a5273e3a501f3b196844c125290780Richard Smith 31963497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne SourceLocation StartLoc = Tok.getLocation(), Loc; 31973497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne if (!endLoc) 31983497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne endLoc = &Loc; 31993497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne 32008828ee7faa42f889ade3bb635dc5f1338be671b1Douglas Gregor do { 3201c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith ParseCXX11AttributeSpecifier(attrs, endLoc); 32026ee326af4e77e6f05973486097884d7431f2108dRichard Smith } while (isCXX11AttributeSpecifier()); 3203bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 32043497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne attrs.Range = SourceRange(StartLoc, *endLoc); 3205bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 3206bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 3207334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ParseMicrosoftAttributes - Parse a Microsoft attribute [Attr] 3208334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// 3209334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute: 3210334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// '[' token-seq ']' 3211334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// 3212334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute-seq: 3213334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ms-attribute[opt] 3214334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ms-attribute ms-attribute-seq 32157f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCallvoid Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs, 32167f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall SourceLocation *endLoc) { 3217334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list"); 3218334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet 3219334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet while (Tok.is(tok::l_square)) { 32206ee326af4e77e6f05973486097884d7431f2108dRichard Smith // FIXME: If this is actually a C++11 attribute, parse it as one. 3221334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet ConsumeBracket(); 3222334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet SkipUntil(tok::r_square, true, true); 32237f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (endLoc) *endLoc = Tok.getLocation(); 3224334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); 3225334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet } 3226334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet} 3227563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3228563a645de82231a55e221fe655b7188bf8369662Francois Pichetvoid Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType, 3229563a645de82231a55e221fe655b7188bf8369662Francois Pichet AccessSpecifier& CurAS) { 32303896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor IfExistsCondition Result; 3231563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (ParseMicrosoftIfExistsCondition(Result)) 3232563a645de82231a55e221fe655b7188bf8369662Francois Pichet return; 3233563a645de82231a55e221fe655b7188bf8369662Francois Pichet 32343896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor BalancedDelimiterTracker Braces(*this, tok::l_brace); 32353896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor if (Braces.consumeOpen()) { 3236563a645de82231a55e221fe655b7188bf8369662Francois Pichet Diag(Tok, diag::err_expected_lbrace); 3237563a645de82231a55e221fe655b7188bf8369662Francois Pichet return; 3238563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3239563a645de82231a55e221fe655b7188bf8369662Francois Pichet 32403896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor switch (Result.Behavior) { 32413896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor case IEB_Parse: 32423896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor // Parse the declarations below. 32433896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor break; 32443896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor 32453896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor case IEB_Dependent: 32463896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists) 32473896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor << Result.IsIfExists; 32483896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor // Fall through to skip. 32493896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor 32503896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor case IEB_Skip: 32513896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor Braces.skipToEnd(); 3252563a645de82231a55e221fe655b7188bf8369662Francois Pichet return; 3253563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3254563a645de82231a55e221fe655b7188bf8369662Francois Pichet 32553896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 3256563a645de82231a55e221fe655b7188bf8369662Francois Pichet // __if_exists, __if_not_exists can nest. 3257563a645de82231a55e221fe655b7188bf8369662Francois Pichet if ((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists))) { 3258563a645de82231a55e221fe655b7188bf8369662Francois Pichet ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS); 3259563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 3260563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3261563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3262563a645de82231a55e221fe655b7188bf8369662Francois Pichet // Check for extraneous top-level semicolon. 3263563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (Tok.is(tok::semi)) { 3264eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith ConsumeExtraSemi(InsideStruct, TagType); 3265563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 3266563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3267563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3268563a645de82231a55e221fe655b7188bf8369662Francois Pichet AccessSpecifier AS = getAccessSpecifierIfPresent(); 3269563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (AS != AS_none) { 3270563a645de82231a55e221fe655b7188bf8369662Francois Pichet // Current token is a C++ access specifier. 3271563a645de82231a55e221fe655b7188bf8369662Francois Pichet CurAS = AS; 3272563a645de82231a55e221fe655b7188bf8369662Francois Pichet SourceLocation ASLoc = Tok.getLocation(); 3273563a645de82231a55e221fe655b7188bf8369662Francois Pichet ConsumeToken(); 3274563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (Tok.is(tok::colon)) 3275563a645de82231a55e221fe655b7188bf8369662Francois Pichet Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation()); 3276563a645de82231a55e221fe655b7188bf8369662Francois Pichet else 3277563a645de82231a55e221fe655b7188bf8369662Francois Pichet Diag(Tok, diag::err_expected_colon); 3278563a645de82231a55e221fe655b7188bf8369662Francois Pichet ConsumeToken(); 3279563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 3280563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3281563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3282563a645de82231a55e221fe655b7188bf8369662Francois Pichet // Parse all the comma separated declarators. 32835f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParseCXXClassMemberDeclaration(CurAS, 0); 3284563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 32853896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor 32863896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor Braces.consumeClose(); 3287563a645de82231a55e221fe655b7188bf8369662Francois Pichet} 3288