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" 18ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo#include "clang/AST/DeclTemplate.h" 19500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h" 2019510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h" 2119510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/ParsedTemplate.h" 22f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall#include "clang/Sema/PrettyDeclStackTrace.h" 2355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Scope.h" 24e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall#include "clang/Sema/SemaDiagnostic.h" 258fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer#include "llvm/ADT/SmallString.h" 268f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattnerusing namespace clang; 278f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner 288f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// ParseNamespace - We know that the current token is a namespace keyword. This 29d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// may either be a top level namespace or a block-level namespace alias. If 30d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// there was an inline keyword, it has already been parsed. 318f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 328f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// namespace-definition: [C++ 7.3: basic.namespace] 338f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// named-namespace-definition 348f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// unnamed-namespace-definition 358f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 368f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// unnamed-namespace-definition: 37d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// 'inline'[opt] 'namespace' attributes[opt] '{' namespace-body '}' 388f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 398f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// named-namespace-definition: 408f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// original-namespace-definition 418f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// extension-namespace-definition 428f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 438f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// original-namespace-definition: 44d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// 'inline'[opt] 'namespace' identifier attributes[opt] 45d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// '{' namespace-body '}' 468f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 478f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// extension-namespace-definition: 48d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// 'inline'[opt] 'namespace' original-namespace-name 49d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl/// '{' namespace-body '}' 501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 518f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// namespace-alias-definition: [C++ 7.3.2: namespace.alias] 528f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 'namespace' identifier '=' qualified-namespace-specifier ';' 538f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner/// 54d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespace(unsigned Context, 55d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl SourceLocation &DeclEnd, 56d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl SourceLocation InlineLoc) { 5704d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner assert(Tok.is(tok::kw_namespace) && "Not a namespace!"); 588f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'. 599735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian ObjCDeclContextSwitch ObjCDC(*this); 60a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian 6149f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor if (Tok.is(tok::code_completion)) { 6223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteNamespaceDecl(getCurScope()); 637d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 647d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return 0; 6549f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor } 66193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 678f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner SourceLocation IdentLoc; 688f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner IdentifierInfo *Ident = 0; 69f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<SourceLocation> ExtraIdentLoc; 70f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<IdentifierInfo*> ExtraIdent; 71f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<SourceLocation> ExtraNamespaceLoc; 726a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor 736a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor Token attrTok; 741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7504d6666eee19bbf25bdfcb8e79eb8b00ace03f0cChris Lattner if (Tok.is(tok::identifier)) { 768f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner Ident = Tok.getIdentifierInfo(); 778f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner IdentLoc = ConsumeToken(); // eat the identifier. 78f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu while (Tok.is(tok::coloncolon) && NextToken().is(tok::identifier)) { 79f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ExtraNamespaceLoc.push_back(ConsumeToken()); 80f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ExtraIdent.push_back(Tok.getIdentifierInfo()); 81f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ExtraIdentLoc.push_back(ConsumeToken()); 82f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 838f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner } 841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 858f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner // Read label attributes, if present. 860b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributes attrs(AttrFactory); 876a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor if (Tok.is(tok::kw___attribute)) { 886a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor attrTok = Tok; 897f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseGNUAttributes(attrs); 906a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor } 911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 926a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor if (Tok.is(tok::equal)) { 93e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber if (Ident == 0) { 94e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber Diag(Tok, diag::err_expected_ident); 95e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber // Skip to end of the definition and eat the ';'. 96e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber SkipUntil(tok::semi); 97e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber return 0; 98e1bb329744ec98ca921bfc4f0888cff7ab4d1bf4Nico Weber } 997f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (!attrs.empty()) 1006a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor Diag(attrTok, diag::err_unexpected_namespace_attributes_alias); 101d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl if (InlineLoc.isValid()) 102d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl Diag(InlineLoc, diag::err_inline_namespace_alias) 103d078e641450bbc5a20df8d3b54f87b27e398acb3Sebastian Redl << FixItHint::CreateRemoval(InlineLoc); 1049735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd); 1056a588dd230c14a364d222d6057bbcf11afbd9ffdDouglas Gregor } 1061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 107f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 1084a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_brace); 1094a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.consumeOpen()) { 110f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (!ExtraIdent.empty()) { 111f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon) 112f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back()); 113f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(Tok, Ident ? diag::err_expected_lbrace : 1155144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner diag::err_expected_ident_lbrace); 116d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 1175144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner } 1181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() || 12023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor getCurScope()->isInObjcMethodScope() || getCurScope()->getBlockParent() || 12123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor getCurScope()->getFnParent()) { 122f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (!ExtraIdent.empty()) { 123f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon) 124f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back()); 125f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 1264a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope); 12795f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor SkipUntil(tok::r_brace, false); 128d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 12995f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor } 13095f1b15ce1b281c8517d77792abe540753fbcc12Douglas Gregor 131f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (!ExtraIdent.empty()) { 132f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu TentativeParsingAction TPA(*this); 133f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu SkipUntil(tok::r_brace, /*StopAtSemi*/false, /*DontConsume*/true); 134f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Token rBraceToken = Tok; 135f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu TPA.Revert(); 136f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 137f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (!rBraceToken.is(tok::r_brace)) { 138f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon) 139f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back()); 140f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } else { 1419910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer std::string NamespaceFix; 142f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu for (std::vector<IdentifierInfo*>::iterator I = ExtraIdent.begin(), 143f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu E = ExtraIdent.end(); I != E; ++I) { 144f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceFix += " { namespace "; 145f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceFix += (*I)->getName(); 146f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 1479910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer 148f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::string RBraces; 1499910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer for (unsigned i = 0, e = ExtraIdent.size(); i != e; ++i) 150f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu RBraces += "} "; 1519910df05e9b5f03043f4d8dc12ea1bbb722664dfBenjamin Kramer 152f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon) 153f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << FixItHint::CreateReplacement(SourceRange(ExtraNamespaceLoc.front(), 154f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ExtraIdentLoc.back()), 155f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceFix) 156f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu << FixItHint::CreateInsertion(rBraceToken.getLocation(), RBraces); 157f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 158f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 159f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 16088e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl // If we're still good, complain about inline namespaces in non-C++0x now. 1617fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith if (InlineLoc.isValid()) 16280ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith Diag(InlineLoc, getLangOpts().CPlusPlus11 ? 1637fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_inline_namespace : diag::ext_inline_namespace); 16488e64ca96d6c00c6f3bd43772cd325bede795d2aSebastian Redl 1655144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner // Enter a scope for the namespace. 1665144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner ParseScope NamespaceScope(this, Scope::DeclScope); 1672d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 168d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl *NamespcDecl = 169acba90f30876b4140b738f0d3dd0e50724053a96Abramo Bagnara Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, NamespaceLoc, 1704a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor IdentLoc, Ident, T.getOpenLocation(), 1714a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor attrs.getList()); 1722d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 173f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc, 174f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall "parsing namespace"); 1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 176f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu // Parse the contents of the namespace. This includes parsing recovery on 177f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu // any improperly nested namespaces. 178f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParseInnerNamespace(ExtraIdentLoc, ExtraIdent, ExtraNamespaceLoc, 0, 1794a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor InlineLoc, attrs, T); 1801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1815144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner // Leave the namespace scope. 1825144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner NamespaceScope.Exit(); 1838ba5d792032f475eb653ca6340eb51068df0fa90Argyrios Kyrtzidis 1844a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor DeclEnd = T.getCloseLocation(); 1854a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Actions.ActOnFinishNamespaceDef(NamespcDecl, DeclEnd); 1862d1c5d313cd0c229cc614e74baa4c5756a4b46f4Argyrios Kyrtzidis 1875144832ae62cf97543b274d4bb88d5f74d0f7a20Chris Lattner return NamespcDecl; 1888f08cb7d0b97786b17ef05e05caa55aad4d6bd39Chris Lattner} 189c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 190f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu/// ParseInnerNamespace - Parse the contents of a namespace. 191f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieuvoid Parser::ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc, 192f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<IdentifierInfo*>& Ident, 193f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu std::vector<SourceLocation>& NamespaceLoc, 194f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu unsigned int index, SourceLocation& InlineLoc, 195f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParsedAttributes& attrs, 1964a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker &Tracker) { 197f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu if (index == Ident.size()) { 198f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 199f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParsedAttributesWithRange attrs(AttrFactory); 2004e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith MaybeParseCXX11Attributes(attrs); 201f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu MaybeParseMicrosoftAttributes(attrs); 202f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParseExternalDeclaration(attrs); 203f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 2044a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor 2054a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor // The caller is what called check -- we are simply calling 2064a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor // the close for it. 2074a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Tracker.consumeClose(); 208f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 209f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu return; 210f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu } 211f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 212f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu // Parse improperly nested namespaces. 213f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParseScope NamespaceScope(this, Scope::DeclScope); 214f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Decl *NamespcDecl = 215f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu Actions.ActOnStartNamespaceDef(getCurScope(), SourceLocation(), 216f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceLoc[index], IdentLoc[index], 2174a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Ident[index], Tracker.getOpenLocation(), 2184a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor attrs.getList()); 219f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 220f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu ParseInnerNamespace(IdentLoc, Ident, NamespaceLoc, ++index, InlineLoc, 2214a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor attrs, Tracker); 222f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 223f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu NamespaceScope.Exit(); 224f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 2254a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Actions.ActOnFinishNamespaceDef(NamespcDecl, Tracker.getCloseLocation()); 226f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu} 227f858bd817e8d6eac58ae496fa96a2f508fbb286fRichard Trieu 228f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// ParseNamespaceAlias - Parse the part after the '=' in a namespace 229f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// alias definition. 230f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson/// 231d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc, 2320b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall SourceLocation AliasLoc, 2330b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall IdentifierInfo *Alias, 2340b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall SourceLocation &DeclEnd) { 235f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson assert(Tok.is(tok::equal) && "Not equal token"); 2361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 237f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson ConsumeToken(); // eat the '='. 2381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 23949f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor if (Tok.is(tok::code_completion)) { 24023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteNamespaceAliasDecl(getCurScope()); 2417d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 2427d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return 0; 24349f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor } 244193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 245f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson CXXScopeSpec SS; 246f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson // Parse (optional) nested-name-specifier. 247efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 248f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson 249f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson if (SS.isInvalid() || Tok.isNot(tok::identifier)) { 250f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson Diag(Tok, diag::err_expected_namespace_name); 251f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson // Skip to end of the definition and eat the ';'. 252f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson SkipUntil(tok::semi); 253d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 254f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson } 255f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson 256f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson // Parse identifier. 25703bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson IdentifierInfo *Ident = Tok.getIdentifierInfo(); 25803bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson SourceLocation IdentLoc = ConsumeToken(); 2591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 260f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson // Eat the ';'. 26197144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner DeclEnd = Tok.getLocation(); 2626869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name, 2636869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner "", tok::semi); 2641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc, Alias, 26603bd5a1e9a54b62b10ae8aeb6eb5245e2031d98bAnders Carlsson SS, IdentLoc, Ident); 267f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson} 268f67606ae2febe3bb0718f05040c6c4bc2c2c3276Anders Carlsson 269c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// ParseLinkage - We know that the current token is a string_literal 270c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// and just before that, that extern was seen. 271c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 272c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// linkage-specification: [C++ 7.5p2: dcl.link] 273c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 'extern' string-literal '{' declaration-seq[opt] '}' 274c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 'extern' string-literal declaration 275c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner/// 2767d64271b162eaf5cae264ff64465b28af623dc17Chris LattnerDecl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) { 277c19923dda3d28f67aab4726cd40bb07032758383Douglas Gregor assert(Tok.is(tok::string_literal) && "Not a string literal!"); 278f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<8> LangBuffer; 279453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor bool Invalid = false; 2805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid); 281453091cc2082e207ea2c2dda645a9bc01b37fb0cDouglas Gregor if (Invalid) 282d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 283c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 28499831e4677a7e2e051af636221694d60ba31fcdbRichard Smith // FIXME: This is incorrect: linkage-specifiers are parsed in translation 28599831e4677a7e2e051af636221694d60ba31fcdbRichard Smith // phase 7, so string-literal concatenation is supposed to occur. 28699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith // extern "" "C" "" "+" "+" { } is legal. 28799831e4677a7e2e051af636221694d60ba31fcdbRichard Smith if (Tok.hasUDSuffix()) 28899831e4677a7e2e051af636221694d60ba31fcdbRichard Smith Diag(Tok, diag::err_invalid_string_udl); 289c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner SourceLocation Loc = ConsumeStringToken(); 290c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 291074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor ParseScope LinkageScope(this, Scope::DeclScope); 292d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl *LinkageSpec 29323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnStartLinkageSpecification(getCurScope(), 294a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara DS.getSourceRange().getBegin(), 295d56638180014e60538cd666cd11fde6d4698e051Benjamin Kramer Loc, Lang, 296a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara Tok.is(tok::l_brace) ? Tok.getLocation() 297074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor : SourceLocation()); 298074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor 2990b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributesWithRange attrs(AttrFactory); 3004e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith MaybeParseCXX11Attributes(attrs); 3017f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseMicrosoftAttributes(attrs); 302193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 303074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor if (Tok.isNot(tok::l_brace)) { 304f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara // Reset the source range in DS, as the leading "extern" 305f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara // does not really belong to the inner declaration ... 306f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara DS.SetRangeStart(SourceLocation()); 307f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara DS.SetRangeEnd(SourceLocation()); 308f41e33c29cd4b21065956129d5e923f3d73d97d3Abramo Bagnara // ... but anyway remember that such an "extern" was seen. 30935f9a196ef897b9559de25aaecd957208f0b4f59Abramo Bagnara DS.setExternInLinkageSpec(true); 3107f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseExternalDeclaration(attrs, &DS); 31123c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec, 312074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor SourceLocation()); 3131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 314f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor 31563a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor DS.abort(); 31663a011378d4b9483ce24400c163cb8d65ea096a5Douglas Gregor 3177f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ProhibitAttributes(attrs); 318bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 3194a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_brace); 3204a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 321f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 3220b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributesWithRange attrs(AttrFactory); 3234e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith MaybeParseCXX11Attributes(attrs); 3247f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseMicrosoftAttributes(attrs); 3257f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseExternalDeclaration(attrs); 326f44515a49b549171dc3ee9faa6281b72609da563Douglas Gregor } 327c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner 3284a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 3297d64271b162eaf5cae264ff64465b28af623dc17Chris Lattner return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec, 3304a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 331c6fdc34ac0183bfa03d65f317c78b7bdac52897eChris Lattner} 332e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 333f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or 334f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive. Assumes that current token is 'using'. 335d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context, 33678b810559d89e996e00684335407443936ce34a1John McCall const ParsedTemplateInfo &TemplateInfo, 33778b810559d89e996e00684335407443936ce34a1John McCall SourceLocation &DeclEnd, 338c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith ParsedAttributesWithRange &attrs, 339c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith Decl **OwnedType) { 340f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(Tok.is(tok::kw_using) && "Not using token"); 3419735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian ObjCDeclContextSwitch ObjCDC(*this); 3429735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian 343f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Eat 'using'. 344f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation UsingLoc = ConsumeToken(); 345f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 34649f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor if (Tok.is(tok::code_completion)) { 34723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteUsing(getCurScope()); 3487d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 3497d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return 0; 35049f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor } 351193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 35278b810559d89e996e00684335407443936ce34a1John McCall // 'using namespace' means this is a using-directive. 35378b810559d89e996e00684335407443936ce34a1John McCall if (Tok.is(tok::kw_namespace)) { 35478b810559d89e996e00684335407443936ce34a1John McCall // Template parameters are always an error here. 35578b810559d89e996e00684335407443936ce34a1John McCall if (TemplateInfo.Kind) { 35678b810559d89e996e00684335407443936ce34a1John McCall SourceRange R = TemplateInfo.getSourceRange(); 35778b810559d89e996e00684335407443936ce34a1John McCall Diag(UsingLoc, diag::err_templated_using_directive) 35878b810559d89e996e00684335407443936ce34a1John McCall << R << FixItHint::CreateRemoval(R); 35978b810559d89e996e00684335407443936ce34a1John McCall } 36078b810559d89e996e00684335407443936ce34a1John McCall 3619735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs); 36278b810559d89e996e00684335407443936ce34a1John McCall } 363bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 364162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Otherwise, it must be a using-declaration or an alias-declaration. 36578b810559d89e996e00684335407443936ce34a1John McCall 36678b810559d89e996e00684335407443936ce34a1John McCall // Using declarations can't have attributes. 3677f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ProhibitAttributes(attrs); 3682f27477a29b6f5365ee545c1cac666cc8b95f518Chris Lattner 3699735c5e60027b26a809df19677ff16a4d13f1321Fariborz Jahanian return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd, 370a28948f34817476d02412fa204cae038e228c827Fariborz Jahanian AS_none, OwnedType); 371f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 372f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 373f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// ParseUsingDirective - Parse C++ using-directive, assumes 374f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// that current token is 'namespace' and 'using' was already parsed. 375f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 376f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-directive: [C++ 7.3.p4: namespace.udir] 377f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'namespace' ::[opt] nested-name-specifier[opt] 378f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// namespace-name ; 379f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// [GNU] using-directive: 380f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'namespace' ::[opt] nested-name-specifier[opt] 381f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// namespace-name attributes[opt] ; 382f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 383d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDirective(unsigned Context, 38478b810559d89e996e00684335407443936ce34a1John McCall SourceLocation UsingLoc, 38578b810559d89e996e00684335407443936ce34a1John McCall SourceLocation &DeclEnd, 3867f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParsedAttributes &attrs) { 387f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token"); 388f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 389f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Eat 'namespace'. 390f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation NamespcLoc = ConsumeToken(); 391f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 39249f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor if (Tok.is(tok::code_completion)) { 39323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteUsingDirective(getCurScope()); 3947d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis cutOffParsing(); 3957d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return 0; 39649f40bd0c9c9de5e74727774fec429b47d36303aDouglas Gregor } 397193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 398f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor CXXScopeSpec SS; 399f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Parse (optional) nested-name-specifier. 400efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 401f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 402f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor IdentifierInfo *NamespcName = 0; 403f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SourceLocation IdentLoc = SourceLocation(); 404f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 405f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // Parse namespace-name. 406823c44e6d73141f642e207980b4021ddcf09897bChris Lattner if (SS.isInvalid() || Tok.isNot(tok::identifier)) { 407f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor Diag(Tok, diag::err_expected_namespace_name); 408f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // If there was invalid namespace name, skip to end of decl, and eat ';'. 409f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor SkipUntil(tok::semi); 410f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor // FIXME: Are there cases, when we would like to call ActOnUsingDirective? 411d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 412f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor } 4131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 414823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Parse identifier. 415823c44e6d73141f642e207980b4021ddcf09897bChris Lattner NamespcName = Tok.getIdentifierInfo(); 416823c44e6d73141f642e207980b4021ddcf09897bChris Lattner IdentLoc = ConsumeToken(); 4171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 418823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Parse (optional) attributes (most likely GNU strong-using extension). 419bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt bool GNUAttr = false; 420bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.is(tok::kw___attribute)) { 421bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt GNUAttr = true; 4227f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseGNUAttributes(attrs); 423bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 425823c44e6d73141f642e207980b4021ddcf09897bChris Lattner // Eat ';'. 42697144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner DeclEnd = Tok.getLocation(); 4276869d8ea1bb7d191b5b290f5a55ee74f2174829aChris Lattner ExpectAndConsume(tok::semi, 4289ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor GNUAttr ? diag::err_expected_semi_after_attribute_list 4299ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor : diag::err_expected_semi_after_namespace_name, 4309ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor "", tok::semi); 431f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 43223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS, 4337f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall IdentLoc, NamespcName, attrs.getList()); 434f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 435f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 436162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// ParseUsingDeclaration - Parse C++ using-declaration or alias-declaration. 437162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// Assumes that 'using' was already seen. 438f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 439f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// using-declaration: [C++ 7.3.p3: namespace.udecl] 440f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 'using' 'typename'[opt] ::[opt] nested-name-specifier 4419cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor/// unqualified-id 4429cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor/// 'using' :: unqualified-id 443f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor/// 444d03de6aaa312d57dcd6e2bc76bed1e89f5c5019dRichard Smith/// alias-declaration: C++11 [dcl.dcl]p1 445d03de6aaa312d57dcd6e2bc76bed1e89f5c5019dRichard Smith/// 'using' identifier attribute-specifier-seq[opt] = type-id ; 446162e1c1b487352434552147967c3dd296ebee2f7Richard Smith/// 447d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseUsingDeclaration(unsigned Context, 44878b810559d89e996e00684335407443936ce34a1John McCall const ParsedTemplateInfo &TemplateInfo, 44978b810559d89e996e00684335407443936ce34a1John McCall SourceLocation UsingLoc, 45078b810559d89e996e00684335407443936ce34a1John McCall SourceLocation &DeclEnd, 451c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith AccessSpecifier AS, 452c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith Decl **OwnedType) { 4539cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor CXXScopeSpec SS; 4547ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall SourceLocation TypenameLoc; 4558d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella bool HasTypenameKeyword = false; 4566b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith ParsedAttributesWithRange Attrs(AttrFactory); 4572edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 4582edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt // FIXME: Simply skip the attributes and diagnose, don't bother parsing them. 4596b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith MaybeParseCXX11Attributes(Attrs); 4606b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith ProhibitAttributes(Attrs); 4616b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith Attrs.clear(); 4626b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith Attrs.Range = SourceRange(); 4639cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 4649cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Ignore optional 'typename'. 46512c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor // FIXME: This is wrong; we should parse this as a typename-specifier. 4669cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (Tok.is(tok::kw_typename)) { 4676b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith TypenameLoc = ConsumeToken(); 4688d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella HasTypenameKeyword = true; 4699cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 4709cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 4719cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Parse nested-name-specifier. 4722db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith IdentifierInfo *LastII = 0; 4732db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false, 4742db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith /*MayBePseudoDtor=*/0, /*IsTypename=*/false, 4752db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith /*LastII=*/&LastII); 4769cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 4779cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Check nested-name specifier. 4789cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (SS.isInvalid()) { 4799cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SkipUntil(tok::semi); 480d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 4819cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4832db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith SourceLocation TemplateKWLoc; 4842db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith UnqualifiedId Name; 4852db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith 486193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // Parse the unqualified-id. We allow parsing of both constructor and 48712c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor // destructor names and allow the action module to diagnose any semantic 48812c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor // errors. 4892db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith // 4902db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith // C++11 [class.qual]p2: 4912db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith // [...] in a using-declaration that is a member-declaration, if the name 4922db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith // specified after the nested-name-specifier is the same as the identifier 4932db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith // or the simple-template-id's template-name in the last component of the 4942db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith // nested-name-specifier, the name is [...] considered to name the 4952db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith // constructor. 4962db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith if (getLangOpts().CPlusPlus11 && Context == Declarator::MemberContext && 4972db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith Tok.is(tok::identifier) && NextToken().is(tok::semi) && 4982db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() && 4992db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith !SS.getScopeRep()->getAsNamespace() && 5002db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith !SS.getScopeRep()->getAsNamespaceAlias()) { 5012db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith SourceLocation IdLoc = ConsumeToken(); 5022db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith ParsedType Type = Actions.getInheritingConstructorName(SS, IdLoc, *LastII); 5032db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith Name.setConstructorName(Type, IdLoc, IdLoc); 5042db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith } else if (ParseUnqualifiedId(SS, /*EnteringContext=*/ false, 5052db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith /*AllowDestructorName=*/ true, 5062db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith /*AllowConstructorName=*/ true, ParsedType(), 5072db075b1d3b16f0100fe06408dfb4ab7d50700a4Richard Smith TemplateKWLoc, Name)) { 5089cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SkipUntil(tok::semi); 509d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 5109cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 511193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 5126b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith MaybeParseCXX11Attributes(Attrs); 513162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 514162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Maybe this is an alias-declaration. 515162e1c1b487352434552147967c3dd296ebee2f7Richard Smith bool IsAliasDecl = Tok.is(tok::equal); 516162e1c1b487352434552147967c3dd296ebee2f7Richard Smith TypeResult TypeAlias; 517162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (IsAliasDecl) { 5186b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith // TODO: Can GNU attributes appear here? 519162e1c1b487352434552147967c3dd296ebee2f7Richard Smith ConsumeToken(); 520162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 52180ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith Diag(Tok.getLocation(), getLangOpts().CPlusPlus11 ? 5227fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::warn_cxx98_compat_alias_declaration : 5237fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith diag::ext_alias_declaration); 524162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 5253e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // Type alias templates cannot be specialized. 5263e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith int SpecKind = -1; 527536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith if (TemplateInfo.Kind == ParsedTemplateInfo::Template && 528536e9c1f103f3e59ed47e35090819eb93596c35bRichard Smith Name.getKind() == UnqualifiedId::IK_TemplateId) 5293e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SpecKind = 0; 5303e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization) 5313e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SpecKind = 1; 5323e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) 5333e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SpecKind = 2; 5343e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (SpecKind != -1) { 5353e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SourceRange Range; 5363e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (SpecKind == 0) 5373e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Range = SourceRange(Name.TemplateId->LAngleLoc, 5383e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Name.TemplateId->RAngleLoc); 5393e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith else 5403e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Range = TemplateInfo.getSourceRange(); 5413e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Diag(Range.getBegin(), diag::err_alias_declaration_specialization) 5423e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith << SpecKind << Range; 5433e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith SkipUntil(tok::semi); 5443e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return 0; 5453e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 5463e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith 547162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Name must be an identifier. 548162e1c1b487352434552147967c3dd296ebee2f7Richard Smith if (Name.getKind() != UnqualifiedId::IK_Identifier) { 549162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Diag(Name.StartLocation, diag::err_alias_declaration_not_identifier); 550162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // No removal fixit: can't recover from this. 551162e1c1b487352434552147967c3dd296ebee2f7Richard Smith SkipUntil(tok::semi); 552162e1c1b487352434552147967c3dd296ebee2f7Richard Smith return 0; 5538d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella } else if (HasTypenameKeyword) 554162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Diag(TypenameLoc, diag::err_alias_declaration_not_identifier) 555162e1c1b487352434552147967c3dd296ebee2f7Richard Smith << FixItHint::CreateRemoval(SourceRange(TypenameLoc, 556162e1c1b487352434552147967c3dd296ebee2f7Richard Smith SS.isNotEmpty() ? SS.getEndLoc() : TypenameLoc)); 557162e1c1b487352434552147967c3dd296ebee2f7Richard Smith else if (SS.isNotEmpty()) 558162e1c1b487352434552147967c3dd296ebee2f7Richard Smith Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier) 559162e1c1b487352434552147967c3dd296ebee2f7Richard Smith << FixItHint::CreateRemoval(SS.getRange()); 560162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 5613e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TypeAlias = ParseTypeName(0, TemplateInfo.Kind ? 5623e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith Declarator::AliasTemplateContext : 5636b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith Declarator::AliasDeclContext, AS, OwnedType, 5646b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith &Attrs); 5652edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt } else { 5662edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt // C++11 attributes are not allowed on a using-declaration, but GNU ones 5672edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt // are. 5686b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith ProhibitAttributes(Attrs); 5692edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 570162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // Parse (optional) attributes (most likely GNU strong-using extension). 5716b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith MaybeParseGNUAttributes(Attrs); 5722edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt } 5731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5749cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Eat ';'. 5759cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor DeclEnd = Tok.getLocation(); 5769cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor ExpectAndConsume(tok::semi, diag::err_expected_semi_after, 5776b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith !Attrs.empty() ? "attributes list" : 578162e1c1b487352434552147967c3dd296ebee2f7Richard Smith IsAliasDecl ? "alias declaration" : "using declaration", 57912c118a8ff9f61a4d63146fe1a5c0d60987f99bbDouglas Gregor tok::semi); 5809cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 58178b810559d89e996e00684335407443936ce34a1John McCall // Diagnose an attempt to declare a templated using-declaration. 582d03de6aaa312d57dcd6e2bc76bed1e89f5c5019dRichard Smith // In C++11, alias-declarations can be templates: 583162e1c1b487352434552147967c3dd296ebee2f7Richard Smith // template <...> using id = type; 5843e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (TemplateInfo.Kind && !IsAliasDecl) { 58578b810559d89e996e00684335407443936ce34a1John McCall SourceRange R = TemplateInfo.getSourceRange(); 58678b810559d89e996e00684335407443936ce34a1John McCall Diag(UsingLoc, diag::err_templated_using_declaration) 58778b810559d89e996e00684335407443936ce34a1John McCall << R << FixItHint::CreateRemoval(R); 58878b810559d89e996e00684335407443936ce34a1John McCall 58978b810559d89e996e00684335407443936ce34a1John McCall // Unfortunately, we have to bail out instead of recovering by 59078b810559d89e996e00684335407443936ce34a1John McCall // ignoring the parameters, just in case the nested name specifier 59178b810559d89e996e00684335407443936ce34a1John McCall // depends on the parameters. 59278b810559d89e996e00684335407443936ce34a1John McCall return 0; 59378b810559d89e996e00684335407443936ce34a1John McCall } 59478b810559d89e996e00684335407443936ce34a1John McCall 595480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor // "typename" keyword is allowed for identifiers only, 596480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor // because it may be a type definition. 5978d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella if (HasTypenameKeyword && Name.getKind() != UnqualifiedId::IK_Identifier) { 598480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor Diag(Name.getSourceRange().getBegin(), diag::err_typename_identifiers_only) 599480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor << FixItHint::CreateRemoval(SourceRange(TypenameLoc)); 6008d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella // Proceed parsing, but reset the HasTypenameKeyword flag. 6018d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella HasTypenameKeyword = false; 602480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor } 603480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor 6043e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith if (IsAliasDecl) { 6053e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams; 6065354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer MultiTemplateParamsArg TemplateParamsArg( 6073e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TemplateParams ? TemplateParams->data() : 0, 6083e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith TemplateParams ? TemplateParams->size() : 0); 6093e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg, 6106b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith UsingLoc, Name, Attrs.getList(), 6116b3d3e54c003b03f16e235ad2ff49e95587bbf92Richard Smith TypeAlias); 6123e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith } 613162e1c1b487352434552147967c3dd296ebee2f7Richard Smith 6148d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella return Actions.ActOnUsingDeclaration(getCurScope(), AS, 6158d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella /* HasUsingKeyword */ true, UsingLoc, 6168d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella SS, Name, Attrs.getList(), 6178d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella HasTypenameKeyword, TypenameLoc); 618f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor} 619f780abc21c39cd4731b9e38f2d2d9f7d1510bd7bDouglas Gregor 620ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer/// ParseStaticAssertDeclaration - Parse C++0x or C11 static_assert-declaration. 621511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// 622c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// [C++0x] static_assert-declaration: 623c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// static_assert ( constant-expression , string-literal ) ; 624c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// 625ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer/// [C11] static_assert-declaration: 626c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne/// _Static_assert ( constant-expression , string-literal ) ; 627511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// 628d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallDecl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){ 629c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne assert((Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) && 630c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne "Not a static_assert declaration"); 631c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne 6324e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11) 633ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer Diag(Tok, diag::ext_c11_static_assert); 634841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith if (Tok.is(tok::kw_static_assert)) 635841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith Diag(Tok, diag::warn_cxx98_compat_static_assert); 636c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne 637511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson SourceLocation StaticAssertLoc = ConsumeToken(); 6381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6394a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 6404a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.consumeOpen()) { 641511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson Diag(Tok, diag::err_expected_lparen); 6423686c71ff92e4357a78993a16a27185f16ab6234Richard Smith SkipMalformedDecl(); 643d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 644511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 6451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 64660d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AssertExpr(ParseConstantExpression()); 647511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson if (AssertExpr.isInvalid()) { 6483686c71ff92e4357a78993a16a27185f16ab6234Richard Smith SkipMalformedDecl(); 649d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 650511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 6511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 652ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi)) 653d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 654ad5f960f9e42568a87bf5e03dce7ad878f9ba6daAnders Carlsson 6550cc323c6bed7206f9743a9775ec8d9cb90655f9cRichard Smith if (!isTokenStringLiteral()) { 65697f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs Diag(Tok, diag::err_expected_string_literal) 65797f8461a2c553f68a258612d2322e4281c3f0915Andy Gibbs << /*Source='static_assert'*/1; 6583686c71ff92e4357a78993a16a27185f16ab6234Richard Smith SkipMalformedDecl(); 659d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 660511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson } 6611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 66260d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AssertMessage(ParseStringLiteralExpression()); 66399831e4677a7e2e051af636221694d60ba31fcdbRichard Smith if (AssertMessage.isInvalid()) { 6643686c71ff92e4357a78993a16a27185f16ab6234Richard Smith SkipMalformedDecl(); 665d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall return 0; 66699831e4677a7e2e051af636221694d60ba31fcdbRichard Smith } 667511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 6684a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 6691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 67097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner DeclEnd = Tok.getLocation(); 6719ba23b4ceacd77cd264501690a7a9e94184ef71bDouglas Gregor ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert); 672511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 6739ae2f076ca5ab1feb3ba95629099ec2319833701John McCall return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, 6749ae2f076ca5ab1feb3ba95629099ec2319833701John McCall AssertExpr.take(), 675a2026c96d3935e7909e049ad9096762844544ed6Abramo Bagnara AssertMessage.take(), 6764a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 677511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson} 678511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson 679a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith/// ParseDecltypeSpecifier - Parse a C++11 decltype specifier. 6806fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 6816fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 'decltype' ( expression ) 682a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith/// 'decltype' ( 'auto' ) [C++1y] 6836fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson/// 68442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid BlaikieSourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) { 68542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie assert((Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) 68642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie && "Not a decltype specifier"); 68742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 68842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie ExprResult Result; 68942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation StartLoc = Tok.getLocation(); 69042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation EndLoc; 6911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 69242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Tok.is(tok::annot_decltype)) { 69342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Result = getExprAnnotation(Tok); 69442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie EndLoc = Tok.getAnnotationEndLoc(); 69542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie ConsumeToken(); 69642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Result.isInvalid()) { 69742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 69842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return EndLoc; 69942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 70042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } else { 701c7b5543ad32a5c265c02e71b2a6f9856440ed13fRichard Smith if (Tok.getIdentifierInfo()->isStr("decltype")) 702c7b5543ad32a5c265c02e71b2a6f9856440ed13fRichard Smith Diag(Tok, diag::warn_cxx98_compat_decltype); 70339304fad1c8a7b7e64121e9ae544b18e460b682cRichard Smith 70442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie ConsumeToken(); 7051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 70642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie BalancedDelimiterTracker T(*this, tok::l_paren); 70742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (T.expectAndConsume(diag::err_expected_lparen_after, 70842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie "decltype", tok::r_paren)) { 70942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 71042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return T.getOpenLocation() == Tok.getLocation() ? 71142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie StartLoc : T.getOpenLocation(); 71242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 7131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 714a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith // Check for C++1y 'decltype(auto)'. 715a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith if (Tok.is(tok::kw_auto)) { 716a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith // No need to disambiguate here: an expression can't start with 'auto', 717a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith // because the typename-specifier in a function-style cast operation can't 718a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith // be 'auto'. 719a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith Diag(Tok.getLocation(), 720a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith getLangOpts().CPlusPlus1y 721a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith ? diag::warn_cxx11_compat_decltype_auto_type_specifier 722a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith : diag::ext_decltype_auto_type_specifier); 723a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith ConsumeToken(); 724a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith } else { 725a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith // Parse the expression 726a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith 727a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith // C++11 [dcl.type.simple]p4: 728a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith // The operand of the decltype specifier is an unevaluated operand. 729a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, 730a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith 0, /*IsDecltype=*/true); 731a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith Result = ParseExpression(); 732a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith if (Result.isInvalid()) { 733a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith DS.SetTypeSpecError(); 734a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith if (SkipUntil(tok::r_paren, /*StopAtSemi=*/true, 735a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith /*DontConsume=*/true)) { 736a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith EndLoc = ConsumeParen(); 7371e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis } else { 738a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith if (PP.isBacktrackEnabled() && Tok.is(tok::semi)) { 739a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith // Backtrack to get the location of the last token before the semi. 740a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith PP.RevertCachedTokens(2); 741a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith ConsumeToken(); // the semi. 742a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith EndLoc = ConsumeAnyToken(); 743a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith assert(Tok.is(tok::semi)); 744a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith } else { 745a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith EndLoc = Tok.getLocation(); 746a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith } 7471e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis } 748a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith return EndLoc; 7491e584697aa795f915cd46afefd4e1141ee356b8cArgyrios Kyrtzidis } 750a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith 751a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith Result = Actions.ActOnDecltypeExpression(Result.take()); 75242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 75342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 75442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // Match the ')' 75542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie T.consumeClose(); 75642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (T.getCloseLocation().isInvalid()) { 75742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 75842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // FIXME: this should return the location of the last token 75942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // that was consumed (by "consumeClose()") 76042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return T.getCloseLocation(); 76142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 76242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 76376f3f69db1416425070177243e9f390122c553e0Richard Smith if (Result.isInvalid()) { 76476f3f69db1416425070177243e9f390122c553e0Richard Smith DS.SetTypeSpecError(); 76576f3f69db1416425070177243e9f390122c553e0Richard Smith return T.getCloseLocation(); 76676f3f69db1416425070177243e9f390122c553e0Richard Smith } 76776f3f69db1416425070177243e9f390122c553e0Richard Smith 76842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie EndLoc = T.getCloseLocation(); 76942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 770a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith assert(!Result.isInvalid()); 7716fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson 7726fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson const char *PrevSpec = 0; 773fec54013fcd0eb72642741584ca04c1bc292bef8John McCall unsigned DiagID; 7746fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson // Check for duplicate type specifiers (e.g. "int decltype(a)"). 775a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith if (Result.get() 776a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith ? DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec, 777a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith DiagID, Result.release()) 778a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith : DS.SetTypeSpecType(DeclSpec::TST_decltype_auto, StartLoc, PrevSpec, 779a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith DiagID)) { 780fec54013fcd0eb72642741584ca04c1bc292bef8John McCall Diag(StartLoc, DiagID) << PrevSpec; 78142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie DS.SetTypeSpecError(); 78242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie } 78342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie return EndLoc; 78442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie} 78542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 78642d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikievoid Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec& DS, 78742d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation StartLoc, 78842d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie SourceLocation EndLoc) { 78942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // make sure we have a token we can turn into an annotation token 79042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (PP.isBacktrackEnabled()) 79142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie PP.RevertCachedTokens(1); 79242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie else 79342d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie PP.EnterToken(Tok); 79442d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie 79542d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Tok.setKind(tok::annot_decltype); 796a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith setExprAnnotation(Tok, 797a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith DS.getTypeSpecType() == TST_decltype ? DS.getRepAsExpr() : 798a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith DS.getTypeSpecType() == TST_decltype_auto ? ExprResult() : 799a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith ExprError()); 80042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Tok.setAnnotationEndLoc(EndLoc); 80142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie Tok.setLocation(StartLoc); 80242d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie PP.AnnotateCachedTokens(Tok); 8036fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson} 8046fd634f4ac59f5923cffadadb99d19f23c18707aAnders Carlsson 805db5d44b775c60166074acd184ca9f1981c10c2a7Sean Huntvoid Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) { 806db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt assert(Tok.is(tok::kw___underlying_type) && 807db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt "Not an underlying type specifier"); 808db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 809db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt SourceLocation StartLoc = ConsumeToken(); 8104a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 8114a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.expectAndConsume(diag::err_expected_lparen_after, 8124a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor "__underlying_type", tok::r_paren)) { 813db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt return; 814db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt } 815db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 816db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt TypeResult Result = ParseTypeName(); 817db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt if (Result.isInvalid()) { 818db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt SkipUntil(tok::r_paren); 819db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt return; 820db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt } 821db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 822db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt // Match the ')' 8234a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 8244a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.getCloseLocation().isInvalid()) 825db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt return; 826db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 827db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt const char *PrevSpec = 0; 828db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt unsigned DiagID; 829ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec, 830db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt DiagID, Result.release())) 831db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt Diag(StartLoc, DiagID) << PrevSpec; 8322d77634e839880704d51656bebd1d2daff661d4eEnea Zaffanella DS.setTypeofParensRange(T.getRange()); 833db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt} 834db5d44b775c60166074acd184ca9f1981c10c2a7Sean Hunt 83509048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// ParseBaseTypeSpecifier - Parse a C++ base-type-specifier which is either a 83609048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class name or decltype-specifier. Note that we only check that the result 83709048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// names a type; semantic analysis will need to verify that the type names a 83809048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class. The result is either a type or null, depending on whether a type 83909048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// name was found. 84042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// 841053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// base-type-specifier: [C++11 class.derived] 84209048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// class-or-decltype 843053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// class-or-decltype: [C++11 class.derived] 84409048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// nested-name-specifier[opt] class-name 84509048df0b3f472091b2204e531d6b6019244884bDavid Blaikie/// decltype-specifier 846053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// class-name: [C++ class.name] 84742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor/// identifier 8487f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor/// simple-template-id 8491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 850053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// In C++98, instead of base-type-specifier, we have: 851053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// 852053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// ::[opt] nested-name-specifier[opt] class-name 85322216eb4fb0936d2488fc03abd285d135c36ff01David BlaikieParser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc, 85422216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie SourceLocation &EndLocation) { 8557fe3878a36750515fb9772414ecb2489cf149d19David Blaikie // Ignore attempts to use typename 8567fe3878a36750515fb9772414ecb2489cf149d19David Blaikie if (Tok.is(tok::kw_typename)) { 8577fe3878a36750515fb9772414ecb2489cf149d19David Blaikie Diag(Tok, diag::err_expected_class_name_not_template) 8587fe3878a36750515fb9772414ecb2489cf149d19David Blaikie << FixItHint::CreateRemoval(Tok.getLocation()); 8597fe3878a36750515fb9772414ecb2489cf149d19David Blaikie ConsumeToken(); 8607fe3878a36750515fb9772414ecb2489cf149d19David Blaikie } 8617fe3878a36750515fb9772414ecb2489cf149d19David Blaikie 862152aa4b87633754801598ee282e1a17c3ec49257David Blaikie // Parse optional nested-name-specifier 863152aa4b87633754801598ee282e1a17c3ec49257David Blaikie CXXScopeSpec SS; 864152aa4b87633754801598ee282e1a17c3ec49257David Blaikie ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 865152aa4b87633754801598ee282e1a17c3ec49257David Blaikie 866152aa4b87633754801598ee282e1a17c3ec49257David Blaikie BaseLoc = Tok.getLocation(); 867152aa4b87633754801598ee282e1a17c3ec49257David Blaikie 86822216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie // Parse decltype-specifier 86942d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // tok == kw_decltype is just error recovery, it can only happen when SS 87042d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie // isn't empty 87142d6d0c91ab089cb252ab2f91c16d4557f458a2cDavid Blaikie if (Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) { 872152aa4b87633754801598ee282e1a17c3ec49257David Blaikie if (SS.isNotEmpty()) 873152aa4b87633754801598ee282e1a17c3ec49257David Blaikie Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype) 874152aa4b87633754801598ee282e1a17c3ec49257David Blaikie << FixItHint::CreateRemoval(SS.getRange()); 87522216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie // Fake up a Declarator to use with ActOnTypeName. 87622216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie DeclSpec DS(AttrFactory); 87722216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie 878b57775709666e50cd925f9fc589d0fd895fc79a6David Blaikie EndLocation = ParseDecltypeSpecifier(DS); 87922216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie 88022216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 88122216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 88222216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie } 88322216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie 8847f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor // Check whether we have a template-id that names a type. 8857f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor if (Tok.is(tok::annot_template_id)) { 88625a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 887d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor if (TemplateId->Kind == TNK_Type_template || 888d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor TemplateId->Kind == TNK_Dependent_template_name) { 889059101f922de6eb765601459925f4c8914420b23Douglas Gregor AnnotateTemplateIdTokenAsType(); 8907f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 8917f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); 892b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType Type = getTypeAnnotation(Tok); 8937f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor EndLocation = Tok.getAnnotationEndLoc(); 8947f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor ConsumeToken(); 89531a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor 89631a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor if (Type) 89731a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return Type; 89831a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return true; 8997f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor } 9007f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 9017f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor // Fall through to produce an error below. 9027f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor } 9037f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor 90442a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor if (Tok.isNot(tok::identifier)) { 9051ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_class_name); 90631a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return true; 90742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor } 90842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 90984d0a19828599e8623223632d59447fd498999cfDouglas Gregor IdentifierInfo *Id = Tok.getIdentifierInfo(); 91084d0a19828599e8623223632d59447fd498999cfDouglas Gregor SourceLocation IdLoc = ConsumeToken(); 91184d0a19828599e8623223632d59447fd498999cfDouglas Gregor 91284d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (Tok.is(tok::less)) { 91384d0a19828599e8623223632d59447fd498999cfDouglas Gregor // It looks the user intended to write a template-id here, but the 91484d0a19828599e8623223632d59447fd498999cfDouglas Gregor // template-name was wrong. Try to fix that. 91584d0a19828599e8623223632d59447fd498999cfDouglas Gregor TemplateNameKind TNK = TNK_Type_template; 91684d0a19828599e8623223632d59447fd498999cfDouglas Gregor TemplateTy Template; 91723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(), 918059101f922de6eb765601459925f4c8914420b23Douglas Gregor &SS, Template, TNK)) { 91984d0a19828599e8623223632d59447fd498999cfDouglas Gregor Diag(IdLoc, diag::err_unknown_template_name) 92084d0a19828599e8623223632d59447fd498999cfDouglas Gregor << Id; 92184d0a19828599e8623223632d59447fd498999cfDouglas Gregor } 922193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 92384d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (!Template) 92484d0a19828599e8623223632d59447fd498999cfDouglas Gregor return true; 92584d0a19828599e8623223632d59447fd498999cfDouglas Gregor 926193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // Form the template name 92784d0a19828599e8623223632d59447fd498999cfDouglas Gregor UnqualifiedId TemplateName; 92884d0a19828599e8623223632d59447fd498999cfDouglas Gregor TemplateName.setIdentifier(Id, IdLoc); 929193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 93084d0a19828599e8623223632d59447fd498999cfDouglas Gregor // Parse the full template-id, then turn it into a type. 931e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), 932e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara TemplateName, true)) 93384d0a19828599e8623223632d59447fd498999cfDouglas Gregor return true; 93484d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (TNK == TNK_Dependent_template_name) 935059101f922de6eb765601459925f4c8914420b23Douglas Gregor AnnotateTemplateIdTokenAsType(); 936193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 93784d0a19828599e8623223632d59447fd498999cfDouglas Gregor // If we didn't end up with a typename token, there's nothing more we 93884d0a19828599e8623223632d59447fd498999cfDouglas Gregor // can do. 93984d0a19828599e8623223632d59447fd498999cfDouglas Gregor if (Tok.isNot(tok::annot_typename)) 94084d0a19828599e8623223632d59447fd498999cfDouglas Gregor return true; 941193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 94284d0a19828599e8623223632d59447fd498999cfDouglas Gregor // Retrieve the type from the annotation token, consume that token, and 94384d0a19828599e8623223632d59447fd498999cfDouglas Gregor // return. 94484d0a19828599e8623223632d59447fd498999cfDouglas Gregor EndLocation = Tok.getAnnotationEndLoc(); 945b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType Type = getTypeAnnotation(Tok); 94684d0a19828599e8623223632d59447fd498999cfDouglas Gregor ConsumeToken(); 94784d0a19828599e8623223632d59447fd498999cfDouglas Gregor return Type; 94884d0a19828599e8623223632d59447fd498999cfDouglas Gregor } 94984d0a19828599e8623223632d59447fd498999cfDouglas Gregor 95042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // We have an identifier; check whether it is actually a type. 951c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain IdentifierInfo *CorrectedII = 0; 952059101f922de6eb765601459925f4c8914420b23Douglas Gregor ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true, 9539e876876afc13aa671cc11a17c19907c599b9ab9Douglas Gregor false, ParsedType(), 954fad03b75e0297546c5d12ec420b5b79d5b7baa2aAbramo Bagnara /*IsCtorOrDtorName=*/false, 955c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain /*NonTrivialTypeSourceInfo=*/true, 956c1fb54265614845ee1e09856af6e46961c6209f4Kaelyn Uhrain &CorrectedII); 957193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam if (!Type) { 958124b878dba5007df0a268ea128a6ad8dc5dd2c5eDouglas Gregor Diag(IdLoc, diag::err_expected_class_name); 95931a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor return true; 96042a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor } 96142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 96242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Consume the identifier. 96384d0a19828599e8623223632d59447fd498999cfDouglas Gregor EndLocation = IdLoc; 9645606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky 9655606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky // Fake up a Declarator to use with ActOnTypeName. 9660b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall DeclSpec DS(AttrFactory); 9675606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky DS.SetRangeStart(IdLoc); 9685606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky DS.SetRangeEnd(EndLocation); 969059101f922de6eb765601459925f4c8914420b23Douglas Gregor DS.getTypeSpecScope() = SS; 9705606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky 9715606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky const char *PrevSpec = 0; 9725606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky unsigned DiagID; 9735606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type); 9745606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky 9755606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 9765606220447c7901ba8d80147ddab893bb7949dd5Nick Lewycky return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); 97742a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor} 97842a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor 979c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCallvoid Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) { 980c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall while (Tok.is(tok::kw___single_inheritance) || 981c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall Tok.is(tok::kw___multiple_inheritance) || 982c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall Tok.is(tok::kw___virtual_inheritance)) { 983c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall IdentifierInfo *AttrName = Tok.getIdentifierInfo(); 984c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall SourceLocation AttrNameLoc = ConsumeToken(); 985c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 98693f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt SourceLocation(), 0, 0, AttributeList::AS_GNU); 987c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall } 988c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall} 989c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall 990c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// Determine whether the following tokens are valid after a type-specifier 991c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// which could be a standalone declaration. This will conservatively return 992c9f351700721150a985f21844fbfec55b04e861dRichard Smith/// true if there's any doubt, and is appropriate for insert-';' fixits. 993139be7007eba3bd491ca50297888be507753a95dRichard Smithbool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) { 994c9f351700721150a985f21844fbfec55b04e861dRichard Smith // This switch enumerates the valid "follow" set for type-specifiers. 995c9f351700721150a985f21844fbfec55b04e861dRichard Smith switch (Tok.getKind()) { 996c9f351700721150a985f21844fbfec55b04e861dRichard Smith default: break; 997c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::semi: // struct foo {...} ; 998c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::star: // struct foo {...} * P; 999c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::amp: // struct foo {...} & R = ... 1000ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith case tok::ampamp: // struct foo {...} && R = ... 1001c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::identifier: // struct foo {...} V ; 1002c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::r_paren: //(struct foo {...} ) {4} 1003c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::annot_cxxscope: // struct foo {...} a:: b; 1004c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::annot_typename: // struct foo {...} a ::b; 1005c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::annot_template_id: // struct foo {...} a<int> ::b; 1006c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::l_paren: // struct foo {...} ( x); 1007c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::comma: // __builtin_offsetof(struct foo{...} , 1008ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith case tok::kw_operator: // struct foo operator ++() {...} 1009c9f351700721150a985f21844fbfec55b04e861dRichard Smith return true; 1010139be7007eba3bd491ca50297888be507753a95dRichard Smith case tok::colon: 1011139be7007eba3bd491ca50297888be507753a95dRichard Smith return CouldBeBitfield; // enum E { ... } : 2; 1012c9f351700721150a985f21844fbfec55b04e861dRichard Smith // Type qualifiers 1013c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_const: // struct foo {...} const x; 1014c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_volatile: // struct foo {...} volatile x; 1015c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_restrict: // struct foo {...} restrict x; 1016ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith // Function specifiers 1017ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith // Note, no 'explicit'. An explicit function must be either a conversion 1018ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith // operator or a constructor. Either way, it can't have a return type. 1019ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith case tok::kw_inline: // struct foo inline f(); 1020ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith case tok::kw_virtual: // struct foo virtual f(); 1021ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith case tok::kw_friend: // struct foo friend f(); 1022c9f351700721150a985f21844fbfec55b04e861dRichard Smith // Storage-class specifiers 1023c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_static: // struct foo {...} static x; 1024c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_extern: // struct foo {...} extern x; 1025c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_typedef: // struct foo {...} typedef x; 1026c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_register: // struct foo {...} register x; 1027c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_auto: // struct foo {...} auto x; 1028c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_mutable: // struct foo {...} mutable x; 1029ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith case tok::kw_thread_local: // struct foo {...} thread_local x; 1030c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::kw_constexpr: // struct foo {...} constexpr x; 1031c9f351700721150a985f21844fbfec55b04e861dRichard Smith // As shown above, type qualifiers and storage class specifiers absolutely 1032c9f351700721150a985f21844fbfec55b04e861dRichard Smith // can occur after class specifiers according to the grammar. However, 1033c9f351700721150a985f21844fbfec55b04e861dRichard Smith // almost no one actually writes code like this. If we see one of these, 1034c9f351700721150a985f21844fbfec55b04e861dRichard Smith // it is much more likely that someone missed a semi colon and the 1035c9f351700721150a985f21844fbfec55b04e861dRichard Smith // type/storage class specifier we're seeing is part of the *next* 1036c9f351700721150a985f21844fbfec55b04e861dRichard Smith // intended declaration, as in: 1037c9f351700721150a985f21844fbfec55b04e861dRichard Smith // 1038c9f351700721150a985f21844fbfec55b04e861dRichard Smith // struct foo { ... } 1039c9f351700721150a985f21844fbfec55b04e861dRichard Smith // typedef int X; 1040c9f351700721150a985f21844fbfec55b04e861dRichard Smith // 1041c9f351700721150a985f21844fbfec55b04e861dRichard Smith // We'd really like to emit a missing semicolon error instead of emitting 1042c9f351700721150a985f21844fbfec55b04e861dRichard Smith // an error on the 'int' saying that you can't have two type specifiers in 1043c9f351700721150a985f21844fbfec55b04e861dRichard Smith // the same declaration of X. Because of this, we look ahead past this 1044c9f351700721150a985f21844fbfec55b04e861dRichard Smith // token to see if it's a type specifier. If so, we know the code is 1045c9f351700721150a985f21844fbfec55b04e861dRichard Smith // otherwise invalid, so we can produce the expected semi error. 1046c9f351700721150a985f21844fbfec55b04e861dRichard Smith if (!isKnownToBeTypeSpecifier(NextToken())) 1047c9f351700721150a985f21844fbfec55b04e861dRichard Smith return true; 1048c9f351700721150a985f21844fbfec55b04e861dRichard Smith break; 1049c9f351700721150a985f21844fbfec55b04e861dRichard Smith case tok::r_brace: // struct bar { struct foo {...} } 1050c9f351700721150a985f21844fbfec55b04e861dRichard Smith // Missing ';' at end of struct is accepted as an extension in C mode. 1051c9f351700721150a985f21844fbfec55b04e861dRichard Smith if (!getLangOpts().CPlusPlus) 1052c9f351700721150a985f21844fbfec55b04e861dRichard Smith return true; 1053c9f351700721150a985f21844fbfec55b04e861dRichard Smith break; 1054ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith // C++11 attributes 1055ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith case tok::l_square: // enum E [[]] x 1056ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith // Note, no tok::kw_alignas here; alignas cannot appertain to a type. 1057ba65f505b7cc2551571b299d05d767e0a892aaaeRichard Smith return getLangOpts().CPlusPlus11 && NextToken().is(tok::l_square); 10588338a9d28c4a9d06b19b1c5df51e70182914e2dfRichard Smith case tok::greater: 10598338a9d28c4a9d06b19b1c5df51e70182914e2dfRichard Smith // template<class T = class X> 10608338a9d28c4a9d06b19b1c5df51e70182914e2dfRichard Smith return getLangOpts().CPlusPlus; 1061c9f351700721150a985f21844fbfec55b04e861dRichard Smith } 1062c9f351700721150a985f21844fbfec55b04e861dRichard Smith return false; 1063c9f351700721150a985f21844fbfec55b04e861dRichard Smith} 1064c9f351700721150a985f21844fbfec55b04e861dRichard Smith 1065e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or 1066e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which 1067e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// until we reach the start of a definition or see a token that 106869730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith/// cannot start a definition. 1069e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1070e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-specifier: [C++ class] 1071e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head '{' member-specification[opt] '}' 1072e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head '{' member-specification[opt] '}' attributes[opt] 1073e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-head: 1074e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key identifier[opt] base-clause[opt] 1075e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key nested-name-specifier identifier base-clause[opt] 1076e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key nested-name-specifier[opt] simple-template-id 1077e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-clause[opt] 1078e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] class-key attributes[opt] identifier[opt] base-clause[opt] 10791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU] class-key attributes[opt] nested-name-specifier 1080e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// identifier base-clause[opt] 10811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [GNU] class-key attributes[opt] nested-name-specifier[opt] 1082e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// simple-template-id base-clause[opt] 1083e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class-key: 1084e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'class' 1085e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'struct' 1086e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'union' 1087e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1088e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// elaborated-type-specifier: [C++ dcl.type.elab] 10891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// class-key ::[opt] nested-name-specifier[opt] identifier 10901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// class-key ::[opt] nested-name-specifier[opt] 'template'[opt] 10911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// simple-template-id 1092e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1093e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// Note that the C++ class-specifier and elaborated-type-specifier, 1094e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// together, subsume the C99 struct-or-union-specifier: 1095e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1096e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union-specifier: [C99 6.7.2.1] 1097e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union identifier[opt] '{' struct-contents '}' 1098e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union identifier 1099e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] struct-or-union attributes[opt] identifier[opt] '{' struct-contents 1100e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// '}' attributes[opt] 1101e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// [GNU] struct-or-union attributes[opt] identifier 1102e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// struct-or-union: 1103e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'struct' 1104e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'union' 11054c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattnervoid Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, 11064c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner SourceLocation StartLoc, DeclSpec &DS, 11074d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor const ParsedTemplateInfo &TemplateInfo, 1108efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor AccessSpecifier AS, 11092e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han bool EnteringContext, DeclSpecContext DSC, 1110ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling ParsedAttributesWithRange &Attributes) { 111117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos DeclSpec::TST TagType; 111217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos if (TagTokKind == tok::kw_struct) 111317d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType = DeclSpec::TST_struct; 111417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos else if (TagTokKind == tok::kw___interface) 111517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType = DeclSpec::TST_interface; 111617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos else if (TagTokKind == tok::kw_class) 111717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType = DeclSpec::TST_class; 111817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos else { 11194c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner assert(TagTokKind == tok::kw_union && "Not a class specifier"); 11204c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner TagType = DeclSpec::TST_union; 11214c97d762d8c5a84f6554e5bfb31d28c90df64158Chris Lattner } 1122e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1123374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor if (Tok.is(tok::code_completion)) { 1124374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor // Code completion for a struct, class, or union name. 112523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.CodeCompleteTag(getCurScope(), TagType); 11267d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return cutOffParsing(); 1127374929f7e88f6c7a96382b3eb4201b721c418372Douglas Gregor } 1128193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 1129926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // C++03 [temp.explicit] 14.7.2/8: 1130926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // The usual access checking rules do not apply to names used to specify 1131926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // explicit instantiations. 1132926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // 1133926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // As an extension we do not perform access checking on the names used to 1134926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // specify explicit specializations either. This is important to allow 1135926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth // specializing traits classes for private types. 113613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // 113713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // Note that we don't suppress if this turns out to be an elaborated 113813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // type specifier. 113913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall bool shouldDelayDiagsInTag = 114013489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation || 114113489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization); 114213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag); 1143926c4b486a08f698cd3a367fd6f1a3a07604358dChandler Carruth 11442edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ParsedAttributesWithRange attrs(AttrFactory); 1145e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If attributes exist after tag, parse them. 1146e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw___attribute)) 11477f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseGNUAttributes(attrs); 1148e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1149f59e17ecf06ac60065e2d02058bd6f21f5d216ccSteve Naroff // If declspecs exist after tag, parse them. 1150b1d397c23e1f8fd8b404d5731d531e7500f7140dJohn McCall while (Tok.is(tok::kw___declspec)) 11517f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ParseMicrosoftDeclSpec(attrs); 1152193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 1153c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall // Parse inheritance specifiers. 1154c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall if (Tok.is(tok::kw___single_inheritance) || 1155c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall Tok.is(tok::kw___multiple_inheritance) || 1156c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall Tok.is(tok::kw___virtual_inheritance)) 1157c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall ParseMicrosoftInheritanceClassAttributes(attrs); 1158c052dbb2d8fe0e23e90d81236aab0f864f712b45John McCall 1159bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // If C++0x attributes exist here, parse them. 1160bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // FIXME: Are we consistent with the ordering of parsing of different 1161bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // styles of attributes? 11624e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith MaybeParseCXX11Attributes(attrs); 11631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 116407fc1ba7553f2f5bf26984091197311decd9028eMichael Han // Source location used by FIXIT to insert misplaced 116507fc1ba7553f2f5bf26984091197311decd9028eMichael Han // C++11 attributes 116607fc1ba7553f2f5bf26984091197311decd9028eMichael Han SourceLocation AttrFixitLoc = Tok.getLocation(); 116707fc1ba7553f2f5bf26984091197311decd9028eMichael Han 116820c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley if (TagType == DeclSpec::TST_struct && 1169b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor !Tok.is(tok::identifier) && 1170b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.getIdentifierInfo() && 1171b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor (Tok.is(tok::kw___is_arithmetic) || 1172b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_convertible) || 117320c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley Tok.is(tok::kw___is_empty) || 1174b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_floating_point) || 1175b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_function) || 117620c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley Tok.is(tok::kw___is_fundamental) || 1177b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_integral) || 1178b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_member_function_pointer) || 1179b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_member_pointer) || 1180b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_pod) || 1181b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_pointer) || 1182b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_same) || 1183877222e2491bbc40a5c74cc100c540983f306b70Douglas Gregor Tok.is(tok::kw___is_scalar) || 1184b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_signed) || 1185b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_unsigned) || 1186b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor Tok.is(tok::kw___is_void))) { 1187688761409155b47c39eb5dae1b8c6c8a9f43307aDouglas Gregor // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the 1188b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // name of struct templates, but some are keywords in GCC >= 4.3 1189b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // and Clang. Therefore, when we see the token sequence "struct 1190b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // X", make X into a normal identifier rather than a keyword, to 1191b467cda8d97a1a18ee1aa62db3b7b21b2c294cebDouglas Gregor // allow libstdc++ 4.2 and libc++ to work properly. 1192646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis Tok.getIdentifierInfo()->RevertTokenIDToIdentifier(); 1193b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor Tok.setKind(tok::identifier); 1194b117a60f7684261ddc8c8f14e8ef8a827e6af814Douglas Gregor } 11951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1196eb83ecde1a822b1c38cd060a85a08c1ac9f82cf8Argyrios Kyrtzidis // Parse the (optional) nested-name-specifier. 1197aa87d33309f505b68c3bfc17486c93e4d224b24fJohn McCall CXXScopeSpec &SS = DS.getTypeSpecScope(); 11984e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus) { 119908d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner // "FOO : BAR" is not a potential typo for "FOO::BAR". 120008d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner ColonProtectionRAIIObject X(*this); 1201193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 1202efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext)) 1203207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall DS.SetTypeSpecError(); 12049ba6166f4a78722e7df8ffbd64eb788bfdf2764aJohn McCall if (SS.isSet()) 120508d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) 120608d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner Diag(Tok, diag::err_expected_ident); 120708d92ecf6e5b1fd23177a08c2312b58d63d863dbChris Lattner } 1208cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor 12092cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams; 12102cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor 1211cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor // Parse the (optional) class name or simple-template-id. 1212e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IdentifierInfo *Name = 0; 1213e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation NameLoc; 121439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateIdAnnotation *TemplateId = 0; 1215e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::identifier)) { 1216e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor Name = Tok.getIdentifierInfo(); 1217e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor NameLoc = ConsumeToken(); 1218193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 12194e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Tok.is(tok::less) && getLangOpts().CPlusPlus) { 1220193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // The name was supposed to refer to a template, but didn't. 12212cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // Eat the template argument list and try to continue parsing this as 12222cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // a class (or template thereof). 12232cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor TemplateArgList TemplateArgs; 12242cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor SourceLocation LAngleLoc, RAngleLoc; 1225059101f922de6eb765601459925f4c8914420b23Douglas Gregor if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, SS, 12262cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor true, LAngleLoc, 1227314b97f8c564b465af605efaee23f91ec18a982bDouglas Gregor TemplateArgs, RAngleLoc)) { 12282cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // We couldn't parse the template argument list at all, so don't 12292cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor // try to give any location information for the list. 12302cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor LAngleLoc = RAngleLoc = SourceLocation(); 12312cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor } 1232193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 12332cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor Diag(NameLoc, diag::err_explicit_spec_non_template) 123417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) 123517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos << (TagType == DeclSpec::TST_class? 0 123617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos : TagType == DeclSpec::TST_struct? 1 123717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos : TagType == DeclSpec::TST_interface? 2 123817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos : 3) 123917d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos << Name 124017d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos << SourceRange(LAngleLoc, RAngleLoc); 124117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos 1242193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam // Strip off the last template parameter list if it was empty, since 1243c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor // we've removed its template argument list. 1244c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) { 1245c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor if (TemplateParams && TemplateParams->size() > 1) { 1246c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor TemplateParams->pop_back(); 1247c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor } else { 1248c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor TemplateParams = 0; 1249193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind 1250c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor = ParsedTemplateInfo::NonTemplate; 1251c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor } 1252c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor } else if (TemplateInfo.Kind 1253c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor == ParsedTemplateInfo::ExplicitInstantiation) { 1254c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor // Pretend this is just a forward declaration. 12552cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor TemplateParams = 0; 1256193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind 12572cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor = ParsedTemplateInfo::NonTemplate; 1258193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc 1259c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor = SourceLocation(); 1260c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor const_cast<ParsedTemplateInfo&>(TemplateInfo).ExternLoc 1261c78c06d81f9838aea4198e4965cc1b26bb0bf838Douglas Gregor = SourceLocation(); 12622cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor } 12632cc782f7932f1069d9fa8bb5c518165802aad68dDouglas Gregor } 126439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor } else if (Tok.is(tok::annot_template_id)) { 126525a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateId = takeTemplateIdAnnotation(Tok); 126639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor NameLoc = ConsumeToken(); 1267cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor 1268059101f922de6eb765601459925f4c8914420b23Douglas Gregor if (TemplateId->Kind != TNK_Type_template && 1269059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->Kind != TNK_Dependent_template_name) { 127039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // The template-name in the simple-template-id refers to 127139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // something other than a class template. Give an appropriate 127239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor // error message and skip to the ';'. 127339a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor SourceRange Range(NameLoc); 127439a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor if (SS.isNotEmpty()) 127539a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor Range.setBegin(SS.getBeginLoc()); 127639a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor 127739a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template) 12786e91f4bd9a05ca2c58ba11d541d8f9dab5514b76Richard Trieu << TemplateId->Name << static_cast<int>(TemplateId->Kind) << Range; 12791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 128039a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor DS.SetTypeSpecError(); 128139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor SkipUntil(tok::semi, false, true); 128239a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor return; 1283cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor } 1284e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1285e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 12867796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // There are four options here. 12877796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - If we are in a trailing return type, this is always just a reference, 12887796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // and we must not try to parse a definition. For instance, 12897796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // [] () -> struct S { }; 12907796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // does not define a type. 12917796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - If we have 'struct foo {...', 'struct foo :...', 12927796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // 'struct foo final :' or 'struct foo final {', then this is a definition. 12937796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - If we have 'struct foo;', then this is either a forward declaration 12947796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // or a friend declaration, which have to be treated differently. 12957796eb5643244f3134834253ce5ea89107ac21c1Richard Smith // - Otherwise we have something like 'struct foo xyz', a reference. 12962e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // 12972e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // We also detect these erroneous cases to provide better diagnostic for 12982e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // C++11 attributes parsing. 12992e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // - attributes follow class name: 13002e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // struct foo [[]] {}; 13012e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // - attributes appear before or after 'final': 13022e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // struct foo [[]] final [[]] {}; 13032e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // 130469730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // However, in type-specifier-seq's, things look like declarations but are 130569730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // just references, e.g. 130669730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // new struct s; 1307d9bafa76f8d6eb9e4f4974ed322217f8df6bb82eSebastian Redl // or 130869730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // &T::operator struct s; 130969730c115c2d0fec2f20609d905d920a5a41b29bRichard Smith // For these, DSC is DSC_type_specifier. 13102e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 13112e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // If there are attributes after class name, parse them. 13124e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith MaybeParseCXX11Attributes(Attributes); 13132e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 1314f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall Sema::TagUseKind TUK; 13157796eb5643244f3134834253ce5ea89107ac21c1Richard Smith if (DSC == DSC_trailing) 13167796eb5643244f3134834253ce5ea89107ac21c1Richard Smith TUK = Sema::TUK_Reference; 13177796eb5643244f3134834253ce5ea89107ac21c1Richard Smith else if (Tok.is(tok::l_brace) || 13187796eb5643244f3134834253ce5ea89107ac21c1Richard Smith (getLangOpts().CPlusPlus && Tok.is(tok::colon)) || 13194e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith (isCXX11FinalKeyword() && 13206f42669b7c0b81b07a15a0483aa5e897ce57cb45David Blaikie (NextToken().is(tok::l_brace) || NextToken().is(tok::colon)))) { 1321d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor if (DS.isFriendSpecified()) { 1322d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // C++ [class.friend]p2: 1323d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // A class shall not be defined in a friend declaration. 1324bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith Diag(Tok.getLocation(), diag::err_friend_decl_defines_type) 1325d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor << SourceRange(DS.getFriendSpecLoc()); 1326d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor 1327d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // Skip everything up to the semicolon, so that this looks like a proper 1328d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // friend class (or template thereof) declaration. 1329d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor SkipUntil(tok::semi, true, true); 1330f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = Sema::TUK_Friend; 1331d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor } else { 1332d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor // Okay, this is a class definition. 1333f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = Sema::TUK_Definition; 1334d85bea2affdd59d83d1be7d24b97f436484c3625Douglas Gregor } 1335150d853343758281f7b0c44e058ea81da45b79beRichard Smith } else if (isCXX11FinalKeyword() && (NextToken().is(tok::l_square) || 1336150d853343758281f7b0c44e058ea81da45b79beRichard Smith NextToken().is(tok::kw_alignas))) { 13372e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // We can't tell if this is a definition or reference 13382e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // until we skipped the 'final' and C++11 attribute specifiers. 13392e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han TentativeParsingAction PA(*this); 13402e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 13412e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // Skip the 'final' keyword. 13422e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han ConsumeToken(); 13432e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 13442e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // Skip C++11 attribute specifiers. 13452e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han while (true) { 13462e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) { 13472e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han ConsumeBracket(); 13482e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han if (!SkipUntil(tok::r_square)) 13492e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han break; 1350150d853343758281f7b0c44e058ea81da45b79beRichard Smith } else if (Tok.is(tok::kw_alignas) && NextToken().is(tok::l_paren)) { 13512e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han ConsumeToken(); 13522e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han ConsumeParen(); 13532e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han if (!SkipUntil(tok::r_paren)) 13542e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han break; 13552e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han } else { 13562e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han break; 13572e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han } 13582e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han } 13592e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 13602e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han if (Tok.is(tok::l_brace) || Tok.is(tok::colon)) 13612e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han TUK = Sema::TUK_Definition; 13622e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han else 13632e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han TUK = Sema::TUK_Reference; 13642e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 13652e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han PA.Revert(); 1366c9f351700721150a985f21844fbfec55b04e861dRichard Smith } else if (DSC != DSC_type_specifier && 1367c9f351700721150a985f21844fbfec55b04e861dRichard Smith (Tok.is(tok::semi) || 1368139be7007eba3bd491ca50297888be507753a95dRichard Smith (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) { 1369f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration; 137017d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos if (Tok.isNot(tok::semi)) { 137117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos // A semicolon was missing after this declaration. Diagnose and recover. 137217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, 137317d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos DeclSpec::getSpecifierName(TagType)); 137417d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos PP.EnterToken(Tok); 137517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos Tok.setKind(tok::semi); 137617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos } 1377c9f351700721150a985f21844fbfec55b04e861dRichard Smith } else 1378f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK = Sema::TUK_Reference; 1379e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 13802e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // Forbid misplaced attributes. In cases of a reference, we pass attributes 13812e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han // to caller to handle. 138207fc1ba7553f2f5bf26984091197311decd9028eMichael Han if (TUK != Sema::TUK_Reference) { 138307fc1ba7553f2f5bf26984091197311decd9028eMichael Han // If this is not a reference, then the only possible 138407fc1ba7553f2f5bf26984091197311decd9028eMichael Han // valid place for C++11 attributes to appear here 138507fc1ba7553f2f5bf26984091197311decd9028eMichael Han // is between class-key and class-name. If there are 138607fc1ba7553f2f5bf26984091197311decd9028eMichael Han // any attributes after class-name, we try a fixit to move 138707fc1ba7553f2f5bf26984091197311decd9028eMichael Han // them to the right place. 138807fc1ba7553f2f5bf26984091197311decd9028eMichael Han SourceRange AttrRange = Attributes.Range; 138907fc1ba7553f2f5bf26984091197311decd9028eMichael Han if (AttrRange.isValid()) { 139007fc1ba7553f2f5bf26984091197311decd9028eMichael Han Diag(AttrRange.getBegin(), diag::err_attributes_not_allowed) 139107fc1ba7553f2f5bf26984091197311decd9028eMichael Han << AttrRange 139207fc1ba7553f2f5bf26984091197311decd9028eMichael Han << FixItHint::CreateInsertionFromRange(AttrFixitLoc, 139307fc1ba7553f2f5bf26984091197311decd9028eMichael Han CharSourceRange(AttrRange, true)) 139407fc1ba7553f2f5bf26984091197311decd9028eMichael Han << FixItHint::CreateRemoval(AttrRange); 139507fc1ba7553f2f5bf26984091197311decd9028eMichael Han 139607fc1ba7553f2f5bf26984091197311decd9028eMichael Han // Recover by adding misplaced attributes to the attribute list 139707fc1ba7553f2f5bf26984091197311decd9028eMichael Han // of the class so they can be applied on the class later. 139807fc1ba7553f2f5bf26984091197311decd9028eMichael Han attrs.takeAllFrom(Attributes); 139907fc1ba7553f2f5bf26984091197311decd9028eMichael Han } 140007fc1ba7553f2f5bf26984091197311decd9028eMichael Han } 14012e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 140213489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // If this is an elaborated type specifier, and we delayed 140313489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall // diagnostics before, just merge them into the current pool. 140413489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall if (shouldDelayDiagsInTag) { 140513489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall diagsFromTag.done(); 140613489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall if (TUK == Sema::TUK_Reference) 140713489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall diagsFromTag.redelay(); 140813489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall } 140913489673b84fafaaf49cf5ae4e3bb9a945524dcbJohn McCall 1410207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error || 1411f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK != Sema::TUK_Definition)) { 1412207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall if (DS.getTypeSpecType() != DeclSpec::TST_error) { 1413207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall // We have a declaration or reference to an anonymous class. 1414207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall Diag(StartLoc, diag::err_anon_type_definition) 1415207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall << DeclSpec::getSpecifierName(TagType); 1416207014eb2b372aa33721e86d90a8a586ba8dc8aeJohn McCall } 1417e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1418e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SkipUntil(tok::comma, true); 1419e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor return; 1420e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1421e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1422ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor // Create the tag portion of the class or class template. 1423d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall DeclResult TagOrTempResult = true; // invalid 1424d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall TypeResult TypeResult = true; // invalid 14254d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 1426402abb55fc2e0cdda5fb1ac90009b1f5f6774906Douglas Gregor bool Owned = false; 1427f1bbbb49f06a7462476cd88166fccda5feb15cabJohn McCall if (TemplateId) { 14284d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // Explicit specialization, class template partial specialization, 14294d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // or explicit instantiation. 14305354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), 143139a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateId->NumArgs); 14324d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && 1433f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK == Sema::TUK_Declaration) { 14344d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // This is an explicit instantiation of a class template. 14352edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 14362edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 14374d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TagOrTempResult 143823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnExplicitInstantiation(getCurScope(), 143945f965581935791a018df829a14dff53c1dd8f47Douglas Gregor TemplateInfo.ExternLoc, 14401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateInfo.TemplateLoc, 14414d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TagType, 14421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump StartLoc, 14434d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor SS, 14442b5289b6fd7e3d9899868410a498c081c9595662John McCall TemplateId->Template, 14451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->TemplateNameLoc, 14461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->LAngleLoc, 14474d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TemplateArgsPtr, 14481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->RAngleLoc, 14497f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall attrs.getList()); 145074256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall 145174256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // Friend template-ids are treated as references unless 145274256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // they have template headers, in which case they're ill-formed 145374256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // (FIXME: "template <class T> friend class A<T>::B<int>;"). 145474256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall // We diagnose this error in ActOnClassTemplateSpecialization. 1455f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall } else if (TUK == Sema::TUK_Reference || 1456f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall (TUK == Sema::TUK_Friend && 145774256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) { 14582edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 145955d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara TypeResult = Actions.ActOnTagTemplateIdType(TUK, TagType, StartLoc, 1460059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->SS, 146155d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara TemplateId->TemplateKWLoc, 1462059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->Template, 1463059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->TemplateNameLoc, 1464059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateId->LAngleLoc, 1465059101f922de6eb765601459925f4c8914420b23Douglas Gregor TemplateArgsPtr, 146655d23c925b058be29b792008ddb7d68f6c4fa9a0Abramo Bagnara TemplateId->RAngleLoc); 14674d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor } else { 14684d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // This is an explicit specialization or a class template 14694d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // partial specialization. 14704d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TemplateParameterLists FakedParamLists; 14714d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { 14724d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // This looks like an explicit instantiation, because we have 14734d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // something like 14744d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // 14754d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // template class Foo<X> 14764d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // 14773f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // but it actually has a definition. Most likely, this was 14784d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // meant to be an explicit specialization, but the user forgot 14794d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // the '<>' after 'template'. 14804985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo // It this is friend declaration however, since it cannot have a 14814985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo // template header, it is most likely that the user meant to 14824985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo // remove the 'template' keyword. 14834985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo assert((TUK == Sema::TUK_Definition || TUK == Sema::TUK_Friend) && 14844985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo "Expected a definition here"); 14854985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo 14864985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo if (TUK == Sema::TUK_Friend) { 14874985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo Diag(DS.getFriendSpecLoc(), 14884985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo diag::err_friend_explicit_instantiation); 14894985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo TemplateParams = 0; 14904985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo } else { 14914985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo SourceLocation LAngleLoc 14924985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc); 14934985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo Diag(TemplateId->TemplateNameLoc, 14944985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo diag::err_explicit_instantiation_with_definition) 14954985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo << SourceRange(TemplateInfo.TemplateLoc) 14964985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo << FixItHint::CreateInsertion(LAngleLoc, "<>"); 14974985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo 14984985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo // Create a fake template parameter list that contains only 14994985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo // "template<>", so that we treat this construct as a class 15004985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo // template specialization. 15014985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo FakedParamLists.push_back( 15024985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo Actions.ActOnTemplateParameterList(0, SourceLocation(), 15034985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo TemplateInfo.TemplateLoc, 15044985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo LAngleLoc, 15054985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo 0, 0, 15064985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo LAngleLoc)); 15074985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo TemplateParams = &FakedParamLists; 15084985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo } 15094d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor } 15104d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor 15114d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor // Build the class template specialization. 15124d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor TagOrTempResult 151323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK, 1514d023aec8907831a18d3514a95b843a7ee06b6b5eDouglas Gregor StartLoc, DS.getModulePrivateSpecLoc(), SS, 15152b5289b6fd7e3d9899868410a498c081c9595662John McCall TemplateId->Template, 15161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->TemplateNameLoc, 15171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->LAngleLoc, 151839a8de10c18365bde7062d8959b7ed525449c561Douglas Gregor TemplateArgsPtr, 15191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateId->RAngleLoc, 15207f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall attrs.getList(), 15215354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer MultiTemplateParamsArg( 1522cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor TemplateParams? &(*TemplateParams)[0] : 0, 1523cc636688c4fd10b1732ce3e33b2b106024d545caDouglas Gregor TemplateParams? TemplateParams->size() : 0)); 15244d9a16f36d3b768672d50e6d02000f982ae448d7Douglas Gregor } 15253f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && 1526f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall TUK == Sema::TUK_Declaration) { 15273f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // Explicit instantiation of a member of a class template 15283f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // specialization, e.g., 15293f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // 15303f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // template struct Outer<int>::Inner; 15313f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // 15322edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 15332edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 15343f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor TagOrTempResult 153523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor = Actions.ActOnExplicitInstantiation(getCurScope(), 153645f965581935791a018df829a14dff53c1dd8f47Douglas Gregor TemplateInfo.ExternLoc, 15371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TemplateInfo.TemplateLoc, 15381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump TagType, StartLoc, SS, Name, 15397f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall NameLoc, attrs.getList()); 15409a34edb710917798aa30263374f624f13b594605John McCall } else if (TUK == Sema::TUK_Friend && 15419a34edb710917798aa30263374f624f13b594605John McCall TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) { 15422edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 15432edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 15449a34edb710917798aa30263374f624f13b594605John McCall TagOrTempResult = 15459a34edb710917798aa30263374f624f13b594605John McCall Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(), 15469a34edb710917798aa30263374f624f13b594605John McCall TagType, StartLoc, SS, 15477f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall Name, NameLoc, attrs.getList(), 15485354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer MultiTemplateParamsArg( 15499a34edb710917798aa30263374f624f13b594605John McCall TemplateParams? &(*TemplateParams)[0] : 0, 15509a34edb710917798aa30263374f624f13b594605John McCall TemplateParams? TemplateParams->size() : 0)); 15513f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor } else { 15522edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition) 15532edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt ProhibitAttributes(attrs); 15547c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo 15557c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo if (TUK == Sema::TUK_Definition && 15567c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { 15577c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo // If the declarator-id is not a template-id, issue a diagnostic and 15587c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo // recover by ignoring the 'template' keyword. 15597c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo Diag(Tok, diag::err_template_defn_explicit_instantiation) 15607c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo << 1 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc); 15614985429d6f0dddbe168ec0ed4de029d56294e644Larisse Voufo TemplateParams = 0; 15627c64ef05e179d29646030e9d453081844ecc537aLarisse Voufo } 15632edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt 1564c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall bool IsDependent = false; 1565c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall 1566a25c4080a490ea2bab6f54094dd75b19eae83770John McCall // Don't pass down template parameter lists if this is just a tag 1567a25c4080a490ea2bab6f54094dd75b19eae83770John McCall // reference. For example, we don't need the template parameters here: 1568a25c4080a490ea2bab6f54094dd75b19eae83770John McCall // template <class T> class A *makeA(T t); 1569a25c4080a490ea2bab6f54094dd75b19eae83770John McCall MultiTemplateParamsArg TParams; 1570a25c4080a490ea2bab6f54094dd75b19eae83770John McCall if (TUK != Sema::TUK_Reference && TemplateParams) 1571a25c4080a490ea2bab6f54094dd75b19eae83770John McCall TParams = 1572a25c4080a490ea2bab6f54094dd75b19eae83770John McCall MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size()); 1573a25c4080a490ea2bab6f54094dd75b19eae83770John McCall 15743f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor // Declaration or definition of a class type 15759a34edb710917798aa30263374f624f13b594605John McCall TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc, 15767f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall SS, Name, NameLoc, attrs.getList(), AS, 1577e761230ae3751b525cadd8066c74ec278ee4ef57Douglas Gregor DS.getModulePrivateSpecLoc(), 1578bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith TParams, Owned, IsDependent, 1579bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith SourceLocation(), false, 1580bdad7a2e21686296b78dac6190b78d11c996f6d7Richard Smith clang::TypeResult()); 1581c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall 1582c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall // If ActOnTag said the type was dependent, try again with the 1583c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall // less common call. 15849a34edb710917798aa30263374f624f13b594605John McCall if (IsDependent) { 15859a34edb710917798aa30263374f624f13b594605John McCall assert(TUK == Sema::TUK_Reference || TUK == Sema::TUK_Friend); 158623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK, 1587193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam SS, Name, StartLoc, NameLoc); 15889a34edb710917798aa30263374f624f13b594605John McCall } 15893f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor } 1590e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1591e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If there is a body, parse it and inform the actions module. 1592f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall if (TUK == Sema::TUK_Definition) { 1593bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall assert(Tok.is(tok::l_brace) || 15944e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie (getLangOpts().CPlusPlus && Tok.is(tok::colon)) || 15954e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith isCXX11FinalKeyword()); 15964e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus) 159707fc1ba7553f2f5bf26984091197311decd9028eMichael Han ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs, TagType, 159807fc1ba7553f2f5bf26984091197311decd9028eMichael Han TagOrTempResult.get()); 159907952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis else 1600212e81cc5151b3c42346e43cfd42499a53ffd39aDouglas Gregor ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get()); 1601e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1602e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1603b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall const char *PrevSpec = 0; 1604b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall unsigned DiagID; 1605b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall bool Result; 1606c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall if (!TypeResult.isInvalid()) { 16070daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, 16080daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara NameLoc.isValid() ? NameLoc : StartLoc, 1609b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall PrevSpec, DiagID, TypeResult.get()); 1610c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall } else if (!TagOrTempResult.isInvalid()) { 16110daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara Result = DS.SetTypeSpecType(TagType, StartLoc, 16120daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara NameLoc.isValid() ? NameLoc : StartLoc, 16130daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara PrevSpec, DiagID, TagOrTempResult.get(), Owned); 1614c4e7019d5c9034a2d84ee4695f8e98dc025ac131John McCall } else { 1615ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor DS.SetTypeSpecError(); 161666e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson return; 161766e9977ddd6b197317d149213b76a9af0d3df4deAnders Carlsson } 16181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1619b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall if (Result) 1620fec54013fcd0eb72642741584ca04c1bc292bef8John McCall Diag(StartLoc, DiagID) << PrevSpec; 1621193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 16224ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // At this point, we've successfully parsed a class-specifier in 'definition' 16234ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // form (e.g. "struct foo { int x; }". While we could just return here, we're 16244ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // going to look at what comes after it to improve error recovery. If an 16254ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // impossible token occurs next, we assume that the programmer forgot a ; at 16264ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // the end of the declaration and recover that way. 16274ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // 1628c9f351700721150a985f21844fbfec55b04e861dRichard Smith // Also enforce C++ [temp]p3: 1629c9f351700721150a985f21844fbfec55b04e861dRichard Smith // In a template-declaration which defines a class, no declarator 1630c9f351700721150a985f21844fbfec55b04e861dRichard Smith // is permitted. 163117d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos if (TUK == Sema::TUK_Definition && 163217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) { 16337d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis if (Tok.isNot(tok::semi)) { 16347d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, 16357d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis DeclSpec::getSpecifierName(TagType)); 16367d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis // Push this token back into the preprocessor and change our current token 16377d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis // to ';' so that the rest of the code recovers as though there were an 16387d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis // ';' after the definition. 16397d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis PP.EnterToken(Tok); 16407d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis Tok.setKind(tok::semi); 16417d033b209e87d1964ee2f8de668934bb1a77bde0Argyrios Kyrtzidis } 16424ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner } 1643e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 1644e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 16451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ParseBaseClause - Parse the base-clause of a C++ class [C++ class.derived]. 1646e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1647e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-clause : [C++ class.derived] 1648e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ':' base-specifier-list 1649e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier-list: 1650e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier '...'[opt] 1651e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier-list ',' base-specifier '...'[opt] 1652d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseBaseClause(Decl *ClassDecl) { 1653e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor assert(Tok.is(tok::colon) && "Not a base clause"); 1654e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 1655e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1656f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Build up an array of parsed base specifiers. 16575f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CXXBaseSpecifier *, 8> BaseInfo; 1658f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor 1659e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor while (true) { 1660e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse a base-specifier. 1661f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor BaseResult Result = ParseBaseSpecifier(ClassDecl); 16625ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor if (Result.isInvalid()) { 1663e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Skip the rest of this base specifier, up until the comma or 1664e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // opening brace. 1665f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor SkipUntil(tok::comma, tok::l_brace, true, true); 1666f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor } else { 1667f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Add this to our array of base specifiers. 16685ac8aff3d7431dc7e4d64d960574a10c9f7e0078Douglas Gregor BaseInfo.push_back(Result.get()); 1669e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1670e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1671e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // If the next token is a comma, consume it and keep reading 1672e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // base-specifiers. 1673e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.isNot(tok::comma)) break; 16741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1675e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Consume the comma. 1676e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 1677e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1678f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor 1679f8268ae3196002bbab6adb830302e79b0f368f13Douglas Gregor // Attach the base specifiers 1680beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo.data(), BaseInfo.size()); 1681e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 1682e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1683e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// ParseBaseSpecifier - Parse a C++ base-specifier. A base-specifier is 1684e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// one entry in the base class list of a class specifier, for example: 1685e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// class foo : public bar, virtual private baz { 1686e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public bar' and 'virtual private baz' are each base-specifiers. 1687e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1688e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// base-specifier: [C++ class.derived] 1689053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// attribute-specifier-seq[opt] base-type-specifier 1690053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// attribute-specifier-seq[opt] 'virtual' access-specifier[opt] 1691053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// base-type-specifier 1692053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// attribute-specifier-seq[opt] access-specifier 'virtual'[opt] 1693053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith/// base-type-specifier 1694d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) { 1695e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor bool IsVirtual = false; 1696e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation StartLoc = Tok.getLocation(); 1697e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1698053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith ParsedAttributesWithRange Attributes(AttrFactory); 1699053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith MaybeParseCXX11Attributes(Attributes); 1700053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith 1701e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the 'virtual' keyword. 1702e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw_virtual)) { 1703e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 1704e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IsVirtual = true; 1705e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1706e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1707053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith CheckMisplacedCXX11Attribute(Attributes, StartLoc); 1708053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith 1709e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse an (optional) access specifier. 1710e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor AccessSpecifier Access = getAccessSpecifierIfPresent(); 171192f883177b162928a8e632e4e3b93fafd2b26072John McCall if (Access != AS_none) 1712e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor ConsumeToken(); 17131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1714053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith CheckMisplacedCXX11Attribute(Attributes, StartLoc); 1715053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith 1716e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Parse the 'virtual' keyword (again!), in case it came after the 1717e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // access specifier. 1718e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (Tok.is(tok::kw_virtual)) { 1719e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor SourceLocation VirtualLoc = ConsumeToken(); 1720e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor if (IsVirtual) { 1721e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Complain about duplicate 'virtual' 17221ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(VirtualLoc, diag::err_dup_virtual) 1723849b243d4065f56742a4677d6dc8277609a151f8Douglas Gregor << FixItHint::CreateRemoval(VirtualLoc); 1724e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1725e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1726e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor IsVirtual = true; 1727e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1728e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1729053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith CheckMisplacedCXX11Attribute(Attributes, StartLoc); 1730053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith 173142a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor // Parse the class-name. 17327f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor SourceLocation EndLocation; 173322216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie SourceLocation BaseLoc; 173422216eb4fb0936d2488fc03abd285d135c36ff01David Blaikie TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation); 173531a19b6989bbf326d2de5ae12e712e2a65ca9c34Douglas Gregor if (BaseType.isInvalid()) 173642a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor return true; 17371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1738f90b27ad077c3339b62befc892382845339f9490Douglas Gregor // Parse the optional ellipsis (for a pack expansion). The ellipsis is 1739f90b27ad077c3339b62befc892382845339f9490Douglas Gregor // actually part of the base-specifier-list grammar productions, but we 1740f90b27ad077c3339b62befc892382845339f9490Douglas Gregor // parse it here for convenience. 1741f90b27ad077c3339b62befc892382845339f9490Douglas Gregor SourceLocation EllipsisLoc; 1742f90b27ad077c3339b62befc892382845339f9490Douglas Gregor if (Tok.is(tok::ellipsis)) 1743f90b27ad077c3339b62befc892382845339f9490Douglas Gregor EllipsisLoc = ConsumeToken(); 1744f90b27ad077c3339b62befc892382845339f9490Douglas Gregor 17451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Find the complete source range for the base-specifier. 17467f43d6764797ab21216421aeb00f4ec314d503d1Douglas Gregor SourceRange Range(StartLoc, EndLocation); 17471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1748e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // Notify semantic analysis that we have parsed a complete 1749e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor // base-specifier. 1750053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith return Actions.ActOnBaseSpecifier(ClassDecl, Range, Attributes, IsVirtual, 1751053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith Access, BaseType.get(), BaseLoc, 1752053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith EllipsisLoc); 1753e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 1754e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor 1755e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// getAccessSpecifierIfPresent - Determine whether the next token is 1756e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// a C++ access-specifier. 1757e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 1758e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// access-specifier: [C++ class.derived] 1759e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'private' 1760e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'protected' 1761e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor/// 'public' 17621eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAccessSpecifier Parser::getAccessSpecifierIfPresent() const { 1763e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor switch (Tok.getKind()) { 1764e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor default: return AS_none; 1765e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_private: return AS_private; 1766e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_protected: return AS_protected; 1767e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor case tok::kw_public: return AS_public; 1768e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor } 1769e37ac4ff1620ed2d7026f52baccbfa022d79ced1Douglas Gregor} 17704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 177174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor/// \brief If the given declarator has any parts for which parsing has to be 1772a058fd4f0a944174295f77169b438510dad389f8Richard Smith/// delayed, e.g., default arguments, create a late-parsed method declaration 1773a058fd4f0a944174295f77169b438510dad389f8Richard Smith/// record to handle the parsing at the end of the class definition. 177474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregorvoid Parser::HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo, 177574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor Decl *ThisDecl) { 1776d33133cdc1af466f9c276249b2621be03867888bEli Friedman // We just declared a member function. If this member function 1777a058fd4f0a944174295f77169b438510dad389f8Richard Smith // has any default arguments, we'll need to parse them later. 1778d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateParsedMethodDeclaration *LateMethod = 0; 17791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump DeclaratorChunk::FunctionTypeInfo &FTI 1780075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara = DeclaratorInfo.getFunctionTypeInfo(); 178174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor 1782d33133cdc1af466f9c276249b2621be03867888bEli Friedman for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) { 1783d33133cdc1af466f9c276249b2621be03867888bEli Friedman if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) { 1784d33133cdc1af466f9c276249b2621be03867888bEli Friedman if (!LateMethod) { 1785d33133cdc1af466f9c276249b2621be03867888bEli Friedman // Push this method onto the stack of late-parsed method 1786d33133cdc1af466f9c276249b2621be03867888bEli Friedman // declarations. 1787d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor LateMethod = new LateParsedMethodDeclaration(this, ThisDecl); 1788d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor getCurrentClass().LateParsedDeclarations.push_back(LateMethod); 178923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor LateMethod->TemplateScope = getCurScope()->isTemplateParamScope(); 1790d33133cdc1af466f9c276249b2621be03867888bEli Friedman 1791d33133cdc1af466f9c276249b2621be03867888bEli Friedman // Add all of the parameters prior to this one (they don't 1792d33133cdc1af466f9c276249b2621be03867888bEli Friedman // have default arguments). 1793d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateMethod->DefaultArgs.reserve(FTI.NumArgs); 1794d33133cdc1af466f9c276249b2621be03867888bEli Friedman for (unsigned I = 0; I < ParamIdx; ++I) 1795d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateMethod->DefaultArgs.push_back( 17968f8210c47797f013e0fb24a26f9c4751b10783feDouglas Gregor LateParsedDefaultArgument(FTI.ArgInfo[I].Param)); 1797d33133cdc1af466f9c276249b2621be03867888bEli Friedman } 1798d33133cdc1af466f9c276249b2621be03867888bEli Friedman 179974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Add this parameter to the list of parameters (it may or may 1800d33133cdc1af466f9c276249b2621be03867888bEli Friedman // not have a default argument). 1801d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateMethod->DefaultArgs.push_back( 1802d33133cdc1af466f9c276249b2621be03867888bEli Friedman LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param, 1803d33133cdc1af466f9c276249b2621be03867888bEli Friedman FTI.ArgInfo[ParamIdx].DefaultArgTokens)); 1804d33133cdc1af466f9c276249b2621be03867888bEli Friedman } 1805d33133cdc1af466f9c276249b2621be03867888bEli Friedman } 1806d33133cdc1af466f9c276249b2621be03867888bEli Friedman} 1807d33133cdc1af466f9c276249b2621be03867888bEli Friedman 18084e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith/// isCXX11VirtSpecifier - Determine whether the given token is a C++11 18091f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier. 18101f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 18111f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier: 18121f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// override 18131f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// final 18144e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard SmithVirtSpecifiers::Specifier Parser::isCXX11VirtSpecifier(const Token &Tok) const { 18154e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().CPlusPlus) 1816cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson return VirtSpecifiers::VS_None; 1817cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 1818b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (Tok.is(tok::identifier)) { 1819b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson IdentifierInfo *II = Tok.getIdentifierInfo(); 18201f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 18217eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson // Initialize the contextual keywords. 18227eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson if (!Ident_final) { 18237eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson Ident_final = &PP.getIdentifierTable().get("final"); 18247eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson Ident_override = &PP.getIdentifierTable().get("override"); 18257eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson } 18267eeb4ec11043d4860361348f2b19299d957d47a9Anders Carlsson 1827b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (II == Ident_override) 1828b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return VirtSpecifiers::VS_Override; 18291f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 1830b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (II == Ident_final) 1831b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return VirtSpecifiers::VS_Final; 1832b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson } 1833b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson 1834b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return VirtSpecifiers::VS_None; 18351f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson} 18361f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 18374e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith/// ParseOptionalCXX11VirtSpecifierSeq - Parse a virt-specifier-seq. 18381f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 18391f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq: 18401f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier 18411f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq virt-specifier 18424e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smithvoid Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS, 1843e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall bool IsInterface) { 1844b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson while (true) { 18454e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier(); 1846b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson if (Specifier == VirtSpecifiers::VS_None) 1847b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson return; 1848b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson 1849b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson // C++ [class.mem]p8: 1850b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson // A virt-specifier-seq shall contain at most one of each virt-specifier. 1851cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson const char *PrevSpec = 0; 185246127a96b6dd6b93aa18d5f7a55bc2db8b52a2c9Anders Carlsson if (VS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec)) 1853b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier) 1854b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson << PrevSpec 1855b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson << FixItHint::CreateRemoval(Tok.getLocation()); 1856b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson 1857e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall if (IsInterface && Specifier == VirtSpecifiers::VS_Final) { 1858e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall Diag(Tok.getLocation(), diag::err_override_control_interface) 1859e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall << VirtSpecifiers::getSpecifierName(Specifier); 1860e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall } else { 186180ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith Diag(Tok.getLocation(), getLangOpts().CPlusPlus11 ? 1862e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall diag::warn_cxx98_compat_override_control_keyword : 1863e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall diag::ext_override_control_keyword) 1864e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall << VirtSpecifiers::getSpecifierName(Specifier); 1865e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall } 1866b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson ConsumeToken(); 1867b971dbdb65149a7cf0c046380186d0204e5b411eAnders Carlsson } 18681f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson} 18691f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson 18704e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith/// isCXX11FinalKeyword - Determine whether the next token is a C++11 18718a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson/// contextual 'final' keyword. 18724e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smithbool Parser::isCXX11FinalKeyword() const { 18734e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().CPlusPlus) 18748a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson return false; 1875cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 18768a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson if (!Tok.is(tok::identifier)) 18778a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson return false; 1878cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 18798a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson // Initialize the contextual keywords. 18808a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson if (!Ident_final) { 18818a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson Ident_final = &PP.getIdentifierTable().get("final"); 18828a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson Ident_override = &PP.getIdentifierTable().get("override"); 1883cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson } 18848a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson 18858a29ba0d66bce99014651f1e3351aef6c3361d3fAnders Carlsson return Tok.getIdentifierInfo() == Ident_final; 1886cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson} 1887cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 18884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration. 18894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 18904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declaration: 18914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// decl-specifier-seq[opt] member-declarator-list[opt] ';' 18924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// function-definition ';'[opt] 18934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO] 18944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// using-declaration [TODO] 1895511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson/// [C++0x] static_assert-declaration 18965aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson/// template-declaration 1897bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner/// [GNU] '__extension__' member-declaration 18984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 18994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator-list: 19004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator 19014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator-list ',' member-declarator 19024cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 19034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declarator: 19041f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// declarator virt-specifier-seq[opt] pure-specifier[opt] 19054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// declarator constant-initializer[opt] 19067a614d8380297fcd2bc23986241905d97222948cRichard Smith/// [C++11] declarator brace-or-equal-initializer[opt] 19074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// identifier[opt] ':' constant-expression 19084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 19091f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq: 19101f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier 19111f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier-seq virt-specifier 19121f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 19131f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// virt-specifier: 19141f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// override 19151f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// final 19161f3b6fdabbb10779a473d6315154d7325ce20aeaAnders Carlsson/// 1917e2b6833d445c7a4ce64f1816c05f176ba1740acaSebastian Redl/// pure-specifier: 19184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// '= 0' 19194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 19204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// constant-initializer: 19214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// '=' constant-expression 19224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 192337b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregorvoid Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, 19245f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen AttributeList *AccessAttrs, 1925c9068d7dd94d439cec66c421115d15303e481025John McCall const ParsedTemplateInfo &TemplateInfo, 1926c9068d7dd94d439cec66c421115d15303e481025John McCall ParsingDeclRAIIObject *TemplateDiags) { 19278a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor if (Tok.is(tok::at)) { 19284e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjC1 && NextToken().isObjCAtKeyword(tok::objc_defs)) 19298a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor Diag(Tok, diag::err_at_defs_cxx); 19308a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor else 19318a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor Diag(Tok, diag::err_at_in_class); 19328a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor 19338a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor ConsumeToken(); 19348a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor SkipUntil(tok::r_brace); 19358a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor return; 19368a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor } 19378a9013d24864272cf5b18c908a267bd7a2bda4c4Douglas Gregor 193860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // Access declarations. 193983a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith bool MalformedTypeSpec = false; 194060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall if (!TemplateInfo.Kind && 194183a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith (Tok.is(tok::identifier) || Tok.is(tok::coloncolon))) { 194283a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith if (TryAnnotateCXXScopeToken()) 194383a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith MalformedTypeSpec = true; 194483a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith 194583a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith bool isAccessDecl; 194683a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith if (Tok.isNot(tok::annot_cxxscope)) 194783a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith isAccessDecl = false; 194883a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith else if (NextToken().is(tok::identifier)) 194960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall isAccessDecl = GetLookAheadToken(2).is(tok::semi); 195060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall else 195160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall isAccessDecl = NextToken().is(tok::kw_operator); 195260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 195360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall if (isAccessDecl) { 195460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // Collect the scope specifier token we annotated earlier. 195560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall CXXScopeSpec SS; 1956efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), 1957efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor /*EnteringContext=*/false); 195860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 195960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // Try to parse an unqualified-id. 1960e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara SourceLocation TemplateKWLoc; 196160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall UnqualifiedId Name; 1962e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), 1963e4b92761b43ced611c417ae478568610f1ad7b1eAbramo Bagnara TemplateKWLoc, Name)) { 196460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall SkipUntil(tok::semi); 196560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall return; 196660fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall } 196760fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 196860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall // TODO: recover from mistakenly-qualified operator declarations. 196960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall if (ExpectAndConsume(tok::semi, 197060fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall diag::err_expected_semi_after, 197160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall "access declaration", 197260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall tok::semi)) 197360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall return; 197460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 197523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnUsingDeclaration(getCurScope(), AS, 19768d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella /* HasUsingKeyword */ false, 19778d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella SourceLocation(), 197860fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall SS, Name, 197960fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall /* AttrList */ 0, 19808d030c7a6f36438f6c7dd977f8be0de0cc781ad5Enea Zaffanella /* HasTypenameKeyword */ false, 198160fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall SourceLocation()); 198260fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall return; 198360fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall } 198460fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall } 198560fa3cfd7aa63c29f9fc2d593bac56a3646337ccJohn McCall 1986511d7aba3b12853fdb88729a0313b80a60eab8adAnders Carlsson // static_assert-declaration 1987c6eb44b321c543c5bcf28727228a0cceced57e2ePeter Collingbourne if (Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) { 198837b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor // FIXME: Check for templates 198997144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner SourceLocation DeclEnd; 199097144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner ParseStaticAssertDeclaration(DeclEnd); 1991682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 1992682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner } 19931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1994682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner if (Tok.is(tok::kw_template)) { 19951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump assert(!TemplateInfo.TemplateParams && 199637b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor "Nested template improperly parsed?"); 199797144fc41a9419bf6d74fc9450e8ef3f6e11f7e0Chris Lattner SourceLocation DeclEnd; 19981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd, 19995f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen AS, AccessAttrs); 2000682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 2001682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner } 20025aeccdbb4bdc94e48c04cacc59fa812af32109b2Anders Carlsson 2003bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner // Handle: member-declaration ::= '__extension__' member-declaration 2004bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner if (Tok.is(tok::kw___extension__)) { 2005bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner // __extension__ silences extension warnings in the subexpression. 2006bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner ExtensionRAIIObject O(Diags); // Use RAII to do this. 2007bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner ConsumeToken(); 20085f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen return ParseCXXClassMemberDeclaration(AS, AccessAttrs, 20095f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen TemplateInfo, TemplateDiags); 2010bc8d56496a6ecdba14769df03d75c001184f8c54Chris Lattner } 20119cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 20124ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it 20134ed5d91db256f7dbe6bf716da0b801004c197254Chris Lattner // is a bitfield. 2014a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner ColonProtectionRAIIObject X(*this); 2015193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 20160b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributesWithRange attrs(AttrFactory); 201752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han ParsedAttributesWithRange FnAttrs(AttrFactory); 20184e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith // Optional C++11 attribute-specifier 20194e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith MaybeParseCXX11Attributes(attrs); 202052b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // We need to keep these attributes for future diagnostic 202152b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // before they are taken over by declaration specifier. 202252b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han FnAttrs.addAll(attrs.getList()); 202352b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han FnAttrs.Range = attrs.Range; 202452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han 20257f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseMicrosoftAttributes(attrs); 2026bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 20279cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (Tok.is(tok::kw_using)) { 20287f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall ProhibitAttributes(attrs); 20291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20309cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor // Eat 'using'. 20319cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SourceLocation UsingLoc = ConsumeToken(); 20329cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 20339cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor if (Tok.is(tok::kw_namespace)) { 20349cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor Diag(UsingLoc, diag::err_using_namespace_in_class); 20359cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SkipUntil(tok::semi, true, true); 2036ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner } else { 20379cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor SourceLocation DeclEnd; 20383e4c6c4c79a03f5cb0c4671d7c282d623c6dc35eRichard Smith // Otherwise, it must be a using-declaration or an alias-declaration. 203978b810559d89e996e00684335407443936ce34a1John McCall ParseUsingDeclaration(Declarator::MemberContext, TemplateInfo, 204078b810559d89e996e00684335407443936ce34a1John McCall UsingLoc, DeclEnd, AS); 20419cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 20429cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor return; 20439cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor } 20449cfbe48a7a20a217fdb2920b29b67ae7941cb116Douglas Gregor 20452287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins // Hold late-parsed attributes so we can attach a Decl to them later. 20462287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins LateParsedAttrList CommonLateParsedAttrs; 20472287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins 20484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // decl-specifier-seq: 20494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the common declaration-specifiers piece. 2050c9068d7dd94d439cec66c421115d15303e481025John McCall ParsingDeclSpec DS(*this, TemplateDiags); 20517f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall DS.takeAttributesFrom(attrs); 205283a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith if (MalformedTypeSpec) 205383a22ecbf52c06b4ee364f3fadcdb0abaf2dabf6Richard Smith DS.SetTypeSpecError(); 20542287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class, 20552287c5e2352fc51cd74e8a9a7725cbf87e41c007DeLesley Hutchins &CommonLateParsedAttrs); 20564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 20575354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer MultiTemplateParamsArg TemplateParams( 2058dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0, 2059dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0); 2060dd4a3b0065b9a7e7b00073df415a798886c090f3John McCall 20614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::semi)) { 20624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 206352b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han 206452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han if (DS.isFriendSpecified()) 206552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han ProhibitAttributes(FnAttrs); 206652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han 2067d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl *TheDecl = 20680f4be74ff0273e505d383f89174ef539828424edChandler Carruth Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS, TemplateParams); 2069c9068d7dd94d439cec66c421115d15303e481025John McCall DS.complete(TheDecl); 207067d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall return; 20714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 207207952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis 207354abf7d4fa3123b8324c09d2a4dfb789fd818403John McCall ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext); 20744867347e82648d3baf09524b98b09c297a5a198fNico Weber VirtSpecifiers VS; 20754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 2076eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // Hold late-parsed attributes so we can attach a Decl to them later. 2077eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski LateParsedAttrList LateParsedAttrs; 2078eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski 2079a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor SourceLocation EqualLoc; 2080a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor bool HasInitializer = false; 2081a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor ExprResult Init; 20823a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.isNot(tok::colon)) { 2083a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner // Don't parse FOO:BAR as if it were a typo for FOO::BAR. 2084a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner ColonProtectionRAIIObject X(*this); 2085a1efc8c8c6460d860d6509b05b341e77ed9bfe87Chris Lattner 20863a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // Parse the first declarator. 20873a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 2088a058fd4f0a944174295f77169b438510dad389f8Richard Smith // Error parsing the declarator? 208910bd36882406cdf4805e35add1ce2f11ab9ae152Douglas Gregor if (!DeclaratorInfo.hasName()) { 20903a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // If so, skip until the semi-colon or a }. 2091d941fa4ff0d0d64b5a541dbd4f99693bff7f6e8dSebastian Redl SkipUntil(tok::r_brace, true, true); 20923a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.is(tok::semi)) 20933a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeToken(); 2094682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 20954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 20964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 20974e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith ParseOptionalCXX11VirtSpecifierSeq(VS, getCurrentClass().IsInterface); 20984867347e82648d3baf09524b98b09c297a5a198fNico Weber 20991b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson // If attributes exist after the declarator, but before an '{', parse them. 2100eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); 21011b2fc0f3e181d99fb34f60e711066fb11628ecd0John Thompson 21026a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet // MSVC permits pure specifier on inline functions declared at class scope. 21036a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet // Hence check for =0 before checking for function definition. 21044e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().MicrosoftExt && Tok.is(tok::equal) && 21056a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet DeclaratorInfo.isFunctionDeclarator() && 21066a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet NextToken().is(tok::numeric_constant)) { 2107a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor EqualLoc = ConsumeToken(); 21086a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet Init = ParseInitializer(); 21096a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet if (Init.isInvalid()) 21106a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet SkipUntil(tok::comma, true, true); 2111a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor else 2112a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor HasInitializer = true; 21136a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet } 21146a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet 211545fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor FunctionDefinitionKind DefinitionKind = FDK_Declaration; 21163a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis // function-definition: 21177a614d8380297fcd2bc23986241905d97222948cRichard Smith // 21187a614d8380297fcd2bc23986241905d97222948cRichard Smith // In C++11, a non-function declarator followed by an open brace is a 21197a614d8380297fcd2bc23986241905d97222948cRichard Smith // braced-init-list for an in-class member initialization, not an 21207a614d8380297fcd2bc23986241905d97222948cRichard Smith // erroneous function definition. 212180ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (Tok.is(tok::l_brace) && !getLangOpts().CPlusPlus11) { 212245fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Definition; 2123e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } else if (DeclaratorInfo.isFunctionDeclarator()) { 21247a614d8380297fcd2bc23986241905d97222948cRichard Smith if (Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) { 212545fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Definition; 2126e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } else if (Tok.is(tok::equal)) { 2127e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt const Token &KW = NextToken(); 212845fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor if (KW.is(tok::kw_default)) 212945fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Defaulted; 213045fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor else if (KW.is(tok::kw_delete)) 213145fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor DefinitionKind = FDK_Deleted; 2132e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } 2133e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } 2134e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt 213552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains 213652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // to a friend declaration, that declaration shall be a definition. 213752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han if (DeclaratorInfo.isFunctionDeclarator() && 213852b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han DefinitionKind != FDK_Definition && DS.isFriendSpecified()) { 213952b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // Diagnose attributes that appear before decl specifier: 214052b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // [[]] friend int foo(); 214152b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han ProhibitAttributes(FnAttrs); 214252b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han } 214352b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han 214445fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor if (DefinitionKind) { 21453a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (!DeclaratorInfo.isFunctionDeclarator()) { 214665ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params); 21473a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ConsumeBrace(); 214865ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu SkipUntil(tok::r_brace, /*StopAtSemi*/false); 214952b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han 21509ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor // Consume the optional ';' 21519ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor if (Tok.is(tok::semi)) 21529ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor ConsumeToken(); 2153682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 21543a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 21553a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis 21563a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { 215765ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu Diag(DeclaratorInfo.getIdentifierLoc(), 215865ba94814f667e6ea1fcbf0896ad496bb7010335Richard Trieu diag::err_function_declared_typedef); 21599ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor 21606f9a445760992a6fbff2c0b08becf35ae9eafa71Richard Smith // Recover by treating the 'typedef' as spurious. 21616f9a445760992a6fbff2c0b08becf35ae9eafa71Richard Smith DS.ClearStorageClassSpecs(); 21623a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 21634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 2164eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski Decl *FunDecl = 21655f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo, TemplateInfo, 216645fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor VS, DefinitionKind, Init); 2167eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski 2168fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer if (FunDecl) { 2169fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) { 2170fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer CommonLateParsedAttrs[i]->addDecl(FunDecl); 2171fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer } 2172fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) { 2173fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer LateParsedAttrs[i]->addDecl(FunDecl); 2174fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer } 2175eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski } 2176eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski LateParsedAttrs.clear(); 2177e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt 2178e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt // Consume the ';' - it's optional unless we have a delete or default 21794b0e6f1da341510c1ad83eaf4c836f3134d0156aRichard Trieu if (Tok.is(tok::semi)) 2180eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith ConsumeExtraSemi(AfterMemberFunctionDefinition); 21819ea416e598fa3cb09d67d514c4519c99abb81321Douglas Gregor 2182682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 21833a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis } 21844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 21854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 21864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator-list: 21874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator 21884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator-list ',' member-declarator 21894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 21905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<Decl *, 8> DeclsInGroup; 219160d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult BitfieldSize; 21921c94c16317c1a35c1549e022958188eea2567089Richard Smith bool ExpectSemi = true; 21934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 21944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis while (1) { 21954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // member-declarator: 21964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // declarator pure-specifier[opt] 21977a614d8380297fcd2bc23986241905d97222948cRichard Smith // declarator brace-or-equal-initializer[opt] 21984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // identifier[opt] ':' constant-expression 21994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.is(tok::colon)) { 22004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 22010e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl BitfieldSize = ParseConstantExpression(); 22020e9eabca263e8922bec0e2b38c8670eba9a39a1fSebastian Redl if (BitfieldSize.isInvalid()) 22034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis SkipUntil(tok::comma, true, true); 22044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 22051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2206e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner // If a simple-asm-expr is present, parse it. 2207e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner if (Tok.is(tok::kw_asm)) { 2208e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner SourceLocation Loc; 220960d7b3a319d84d688752be3870615ac0f111fb16John McCall ExprResult AsmLabel(ParseSimpleAsm(&Loc)); 2210e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner if (AsmLabel.isInvalid()) 2211e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner SkipUntil(tok::comma, true, true); 2212e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner 2213e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner DeclaratorInfo.setAsmLabel(AsmLabel.release()); 2214e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner DeclaratorInfo.SetRangeEnd(Loc); 2215e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner } 2216e6563256a4b3b9fee70ce3335d28406607c1faafChris Lattner 22174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If attributes exist after the declarator, parse them. 2218eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); 22194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 22207a614d8380297fcd2bc23986241905d97222948cRichard Smith // FIXME: When g++ adds support for this, we'll need to check whether it 22217a614d8380297fcd2bc23986241905d97222948cRichard Smith // goes before or after the GNU attributes and __asm__. 22224e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith ParseOptionalCXX11VirtSpecifierSeq(VS, getCurrentClass().IsInterface); 22237a614d8380297fcd2bc23986241905d97222948cRichard Smith 2224ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith InClassInitStyle HasInClassInit = ICIS_NoInit; 2225a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor if ((Tok.is(tok::equal) || Tok.is(tok::l_brace)) && !HasInitializer) { 22267a614d8380297fcd2bc23986241905d97222948cRichard Smith if (BitfieldSize.get()) { 22277a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(Tok, diag::err_bitfield_member_init); 22287a614d8380297fcd2bc23986241905d97222948cRichard Smith SkipUntil(tok::comma, true, true); 22297a614d8380297fcd2bc23986241905d97222948cRichard Smith } else { 2230147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor HasInitializer = true; 2231ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith if (!DeclaratorInfo.isDeclarationOfFunction() && 2232ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith DeclaratorInfo.getDeclSpec().getStorageClassSpec() 2233ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith != DeclSpec::SCS_typedef) 2234ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith HasInClassInit = Tok.is(tok::equal) ? ICIS_CopyInit : ICIS_ListInit; 22357a614d8380297fcd2bc23986241905d97222948cRichard Smith } 22367a614d8380297fcd2bc23986241905d97222948cRichard Smith } 22377a614d8380297fcd2bc23986241905d97222948cRichard Smith 223807952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // NOTE: If Sema is the Action module and declarator is an instance field, 2239682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner // this call will *not* return the created decl; It will return null. 224007952324dda0e758c17f8bc3015793c65c51c48cArgyrios Kyrtzidis // See Sema::ActOnCXXMemberDeclarator for details. 224167d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall 2242fc35cbca942ccdfe43742c1d786ed168517e0a47Rafael Espindola NamedDecl *ThisDecl = 0; 224367d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall if (DS.isFriendSpecified()) { 224452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains 224552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // to a friend declaration, that declaration shall be a definition. 224652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // 224752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // Diagnose attributes appear after friend member function declarator: 224852b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han // foo [[]] (); 224952b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han SmallVector<SourceRange, 4> Ranges; 225052b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han DeclaratorInfo.getCXX11AttributeRanges(Ranges); 225152b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han if (!Ranges.empty()) { 225209d19efaa147762f84aed55efa7930bb3616a4e5Craig Topper for (SmallVectorImpl<SourceRange>::iterator I = Ranges.begin(), 225352b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han E = Ranges.end(); I != E; ++I) { 225452b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han Diag((*I).getBegin(), diag::err_attributes_not_allowed) 225552b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han << *I; 225652b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han } 225752b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han } 225852b501cd723d56efe3ad2ab708c2b75530fe6caaMichael Han 2259bbbcdd9cc06b6078939129330ecc9bda3310984dJohn McCall // TODO: handle initializers, bitfields, 'delete' 226023c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo, 22613fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer TemplateParams); 226237b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor } else { 226323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, 226467d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall DeclaratorInfo, 22653fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer TemplateParams, 226667d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall BitfieldSize.release(), 2267ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith VS, HasInClassInit); 2268ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 2269ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo if (VarTemplateDecl *VT = 2270ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo ThisDecl ? dyn_cast<VarTemplateDecl>(ThisDecl) : 0) 2271ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo // Re-direct this decl to refer to the templated decl so that we can 2272ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo // initialize it. 2273ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo ThisDecl = VT->getTemplatedDecl(); 2274ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 2275fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer if (ThisDecl && AccessAttrs) 22765f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs, 22775f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen false, true); 227837b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor } 2279eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski 2280147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // Handle the initializer. 22811d87fbaeea4a9fbbd73b3a53641f59f1673098e5David Blaikie if (HasInClassInit != ICIS_NoInit && 22821d87fbaeea4a9fbbd73b3a53641f59f1673098e5David Blaikie DeclaratorInfo.getDeclSpec().getStorageClassSpec() != 22831d87fbaeea4a9fbbd73b3a53641f59f1673098e5David Blaikie DeclSpec::SCS_static) { 2284147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // The initializer was deferred; parse it and cache the tokens. 2285fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer Diag(Tok, getLangOpts().CPlusPlus11 2286fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer ? diag::warn_cxx98_compat_nonstatic_member_init 2287fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer : diag::ext_nonstatic_member_init); 22887fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 22897a614d8380297fcd2bc23986241905d97222948cRichard Smith if (DeclaratorInfo.isArrayOfUnknownBound()) { 2290ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith // C++11 [dcl.array]p3: An array bound may also be omitted when the 2291ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith // declarator is followed by an initializer. 22927a614d8380297fcd2bc23986241905d97222948cRichard Smith // 22937a614d8380297fcd2bc23986241905d97222948cRichard Smith // A brace-or-equal-initializer for a member-declarator is not an 22943164c14cadbb09a05ba811602221e9156077cf44David Blaikie // initializer in the grammar, so this is ill-formed. 22957a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(Tok, diag::err_incomplete_array_member_init); 22967a614d8380297fcd2bc23986241905d97222948cRichard Smith SkipUntil(tok::comma, true, true); 2297fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer 2298fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer // Avoid later warnings about a class member of incomplete type. 22993164c14cadbb09a05ba811602221e9156077cf44David Blaikie if (ThisDecl) 23003164c14cadbb09a05ba811602221e9156077cf44David Blaikie ThisDecl->setInvalidDecl(); 23017a614d8380297fcd2bc23986241905d97222948cRichard Smith } else 23027a614d8380297fcd2bc23986241905d97222948cRichard Smith ParseCXXNonStaticMemberInitializer(ThisDecl); 2303147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor } else if (HasInitializer) { 2304147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // Normal initializer. 2305a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor if (!Init.isUsable()) 2306fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer Init = ParseCXXMemberInitializer( 2307fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc); 2308fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer 2309147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor if (Init.isInvalid()) 2310147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor SkipUntil(tok::comma, true, true); 2311147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor else if (ThisDecl) 231233deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl Actions.AddInitializerToDecl(ThisDecl, Init.get(), EqualLoc.isInvalid(), 2313a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith DS.containsPlaceholderType()); 2314fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static) 2315147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor // No initializer. 2316a2c3646c35dd09d21b74826240aa916545b1873fRichard Smith Actions.ActOnUninitializedDecl(ThisDecl, DS.containsPlaceholderType()); 2317fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer 2318147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor if (ThisDecl) { 2319fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer if (!ThisDecl->isInvalidDecl()) { 2320fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer // Set the Decl for any late parsed attributes 2321fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) 2322fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer CommonLateParsedAttrs[i]->addDecl(ThisDecl); 2323fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer 2324fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) 2325fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer LateParsedAttrs[i]->addDecl(ThisDecl); 2326fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer } 2327147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor Actions.FinalizeDeclaration(ThisDecl); 2328147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor DeclsInGroup.push_back(ThisDecl); 2329fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer 2330fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer if (DeclaratorInfo.isFunctionDeclarator() && 2331fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer DeclaratorInfo.getDeclSpec().getStorageClassSpec() != 2332fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer DeclSpec::SCS_typedef) 2333fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl); 2334147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor } 2335fcbe20811e3848869054ad13352cbb431bd423ebDavid Majnemer LateParsedAttrs.clear(); 2336147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor 2337147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor DeclaratorInfo.complete(ThisDecl); 23387a614d8380297fcd2bc23986241905d97222948cRichard Smith 23394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If we don't have a comma, it is either the end of the list (a ';') 23404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // or an error, bail out. 23414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (Tok.isNot(tok::comma)) 23424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 23431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 23444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Consume the comma. 23451c94c16317c1a35c1549e022958188eea2567089Richard Smith SourceLocation CommaLoc = ConsumeToken(); 23461c94c16317c1a35c1549e022958188eea2567089Richard Smith 23471c94c16317c1a35c1549e022958188eea2567089Richard Smith if (Tok.isAtStartOfLine() && 23481c94c16317c1a35c1549e022958188eea2567089Richard Smith !MightBeDeclarator(Declarator::MemberContext)) { 23491c94c16317c1a35c1549e022958188eea2567089Richard Smith // This comma was followed by a line-break and something which can't be 23501c94c16317c1a35c1549e022958188eea2567089Richard Smith // the start of a declarator. The comma was probably a typo for a 23511c94c16317c1a35c1549e022958188eea2567089Richard Smith // semicolon. 23521c94c16317c1a35c1549e022958188eea2567089Richard Smith Diag(CommaLoc, diag::err_expected_semi_declaration) 23531c94c16317c1a35c1549e022958188eea2567089Richard Smith << FixItHint::CreateReplacement(CommaLoc, ";"); 23541c94c16317c1a35c1549e022958188eea2567089Richard Smith ExpectSemi = false; 23551c94c16317c1a35c1549e022958188eea2567089Richard Smith break; 23561c94c16317c1a35c1549e022958188eea2567089Richard Smith } 23571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 23584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the next declarator. 23594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis DeclaratorInfo.clear(); 23604867347e82648d3baf09524b98b09c297a5a198fNico Weber VS.clear(); 2361147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor BitfieldSize = true; 2362a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor Init = true; 2363a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor HasInitializer = false; 23647984de35644701c0d94336da7f2215d4c26d9f5bRichard Smith DeclaratorInfo.setCommaLoc(CommaLoc); 23651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2366ad017fa7a4df7389d245d02a49b3c79ed70bedb9Bill Wendling // Attributes are only allowed on the second declarator. 23677f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseGNUAttributes(DeclaratorInfo); 23684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 23693a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis if (Tok.isNot(tok::colon)) 23703a9fdb4742b21c0a3c27f18c5e4e94bab6f9e64cArgyrios Kyrtzidis ParseDeclarator(DeclaratorInfo); 23714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 23724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 23731c94c16317c1a35c1549e022958188eea2567089Richard Smith if (ExpectSemi && 23741c94c16317c1a35c1549e022958188eea2567089Richard Smith ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) { 2375ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner // Skip to end of block or statement. 2376ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner SkipUntil(tok::r_brace, true, true); 2377ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner // If we stopped at a ';', eat it. 2378ae50d501f463d7032320ec31840f60ae68df3a55Chris Lattner if (Tok.is(tok::semi)) ConsumeToken(); 2379682bf92db408a6cbc3d37b5496a99b6ef85041ecChris Lattner return; 23804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 23814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 23824549d7ffc15bdd7ab860aa68db089d9f559b79e7Rafael Espindola Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup); 23834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 23844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 23857a614d8380297fcd2bc23986241905d97222948cRichard Smith/// ParseCXXMemberInitializer - Parse the brace-or-equal-initializer or 23867a614d8380297fcd2bc23986241905d97222948cRichard Smith/// pure-specifier. Also detect and reject any attempted defaulted/deleted 23877a614d8380297fcd2bc23986241905d97222948cRichard Smith/// function definition. The location of the '=', if any, will be placed in 23887a614d8380297fcd2bc23986241905d97222948cRichard Smith/// EqualLoc. 23897a614d8380297fcd2bc23986241905d97222948cRichard Smith/// 23907a614d8380297fcd2bc23986241905d97222948cRichard Smith/// pure-specifier: 23917a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '= 0' 239233deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// 23937a614d8380297fcd2bc23986241905d97222948cRichard Smith/// brace-or-equal-initializer: 23947a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '=' initializer-expression 239533deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// braced-init-list 239633deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// 23977a614d8380297fcd2bc23986241905d97222948cRichard Smith/// initializer-clause: 23987a614d8380297fcd2bc23986241905d97222948cRichard Smith/// assignment-expression 239933deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// braced-init-list 240033deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl/// 24017a614d8380297fcd2bc23986241905d97222948cRichard Smith/// defaulted/deleted function-definition: 24027a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '=' 'default' 24037a614d8380297fcd2bc23986241905d97222948cRichard Smith/// '=' 'delete' 24047a614d8380297fcd2bc23986241905d97222948cRichard Smith/// 24057a614d8380297fcd2bc23986241905d97222948cRichard Smith/// Prior to C++0x, the assignment-expression in an initializer-clause must 24067a614d8380297fcd2bc23986241905d97222948cRichard Smith/// be a constant-expression. 2407552e29985a710f4ced62b39d70557501bd31ca9bDouglas GregorExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction, 24087a614d8380297fcd2bc23986241905d97222948cRichard Smith SourceLocation &EqualLoc) { 24097a614d8380297fcd2bc23986241905d97222948cRichard Smith assert((Tok.is(tok::equal) || Tok.is(tok::l_brace)) 24107a614d8380297fcd2bc23986241905d97222948cRichard Smith && "Data member initializer not starting with '=' or '{'"); 24117a614d8380297fcd2bc23986241905d97222948cRichard Smith 2412552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor EnterExpressionEvaluationContext Context(Actions, 2413552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor Sema::PotentiallyEvaluated, 2414552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor D); 24157a614d8380297fcd2bc23986241905d97222948cRichard Smith if (Tok.is(tok::equal)) { 24167a614d8380297fcd2bc23986241905d97222948cRichard Smith EqualLoc = ConsumeToken(); 24177a614d8380297fcd2bc23986241905d97222948cRichard Smith if (Tok.is(tok::kw_delete)) { 24187a614d8380297fcd2bc23986241905d97222948cRichard Smith // In principle, an initializer of '= delete p;' is legal, but it will 24197a614d8380297fcd2bc23986241905d97222948cRichard Smith // never type-check. It's better to diagnose it as an ill-formed expression 24207a614d8380297fcd2bc23986241905d97222948cRichard Smith // than as an ill-formed deleted non-function member. 24217a614d8380297fcd2bc23986241905d97222948cRichard Smith // An initializer of '= delete p, foo' will never be parsed, because 24227a614d8380297fcd2bc23986241905d97222948cRichard Smith // a top-level comma always ends the initializer expression. 24237a614d8380297fcd2bc23986241905d97222948cRichard Smith const Token &Next = NextToken(); 24247a614d8380297fcd2bc23986241905d97222948cRichard Smith if (IsFunction || Next.is(tok::semi) || Next.is(tok::comma) || 24257a614d8380297fcd2bc23986241905d97222948cRichard Smith Next.is(tok::eof)) { 24267a614d8380297fcd2bc23986241905d97222948cRichard Smith if (IsFunction) 24277a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration) 24287a614d8380297fcd2bc23986241905d97222948cRichard Smith << 1 /* delete */; 24297a614d8380297fcd2bc23986241905d97222948cRichard Smith else 24307a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(ConsumeToken(), diag::err_deleted_non_function); 24317a614d8380297fcd2bc23986241905d97222948cRichard Smith return ExprResult(); 24327a614d8380297fcd2bc23986241905d97222948cRichard Smith } 24337a614d8380297fcd2bc23986241905d97222948cRichard Smith } else if (Tok.is(tok::kw_default)) { 24347a614d8380297fcd2bc23986241905d97222948cRichard Smith if (IsFunction) 24357a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(Tok, diag::err_default_delete_in_multiple_declaration) 24367a614d8380297fcd2bc23986241905d97222948cRichard Smith << 0 /* default */; 24377a614d8380297fcd2bc23986241905d97222948cRichard Smith else 24387a614d8380297fcd2bc23986241905d97222948cRichard Smith Diag(ConsumeToken(), diag::err_default_special_members); 24397a614d8380297fcd2bc23986241905d97222948cRichard Smith return ExprResult(); 24407a614d8380297fcd2bc23986241905d97222948cRichard Smith } 24417a614d8380297fcd2bc23986241905d97222948cRichard Smith 244233deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl } 244333deb35535aebe81bed0eaf5c14f3032276a086eSebastian Redl return ParseInitializer(); 24447a614d8380297fcd2bc23986241905d97222948cRichard Smith} 24457a614d8380297fcd2bc23986241905d97222948cRichard Smith 24464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseCXXMemberSpecification - Parse the class definition. 24474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 24484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-specification: 24494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// member-declaration member-specification[opt] 24504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// access-specifier ':' member-specification[opt] 24514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// 245217d35c36fbae764fcd68fa8b31624078a033aabcJoao Matosvoid Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, 245307fc1ba7553f2f5bf26984091197311decd9028eMichael Han SourceLocation AttrFixitLoc, 2454053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith ParsedAttributesWithRange &Attrs, 245517d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos unsigned TagType, Decl *TagDecl) { 245617d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos assert((TagType == DeclSpec::TST_struct || 245717d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType == DeclSpec::TST_interface || 245817d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType == DeclSpec::TST_union || 245917d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos TagType == DeclSpec::TST_class) && "Invalid TagType!"); 246017d35c36fbae764fcd68fa8b31624078a033aabcJoao Matos 2461f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc, 2462f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall "parsing struct/union/class body"); 24631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 246426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // Determine whether this is a non-nested class. Note that local 246526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // classes are *not* considered to be nested classes. 246626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor bool NonNestedClass = true; 246726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (!ClassStack.empty()) { 246823c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor for (const Scope *S = getCurScope(); S; S = S->getParent()) { 246926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (S->isClassScope()) { 247026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // We're inside a class scope, so this is a nested class. 247126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor NonNestedClass = false; 2472e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall 2473e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall // The Microsoft extension __interface does not permit nested classes. 2474e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall if (getCurrentClass().IsInterface) { 2475e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall Diag(RecordLoc, diag::err_invalid_member_in_interface) 2476e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall << /*ErrorType=*/6 2477e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall << (isa<NamedDecl>(TagDecl) 2478e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall ? cast<NamedDecl>(TagDecl)->getQualifiedNameAsString() 2479e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall : "<anonymous>"); 2480e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall } 248126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor break; 248226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 248326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor 248426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if ((S->getFlags() & Scope::FnScope)) { 248526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // If we're in a function or function template declared in the 248626997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // body of a class, then this is a local class rather than a 248726997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor // nested class. 248826997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor const Scope *Parent = S->getParent(); 248926997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (Parent->isTemplateParamScope()) 249026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor Parent = Parent->getParent(); 249126997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor if (Parent->isClassScope()) 249226997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor break; 249326997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 249426997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 249526997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor } 24964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 24974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Enter a scope for the class. 24983218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope); 24994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 25006569d68745c8213709740337d2be52b031384f58Douglas Gregor // Note that we are parsing a new (potentially-nested) class definition. 2501e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass, 2502e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall TagType == DeclSpec::TST_interface); 25036569d68745c8213709740337d2be52b031384f58Douglas Gregor 2504ddc29e116db3c3f4144355e67a0137b38b6bb6d1Douglas Gregor if (TagDecl) 250523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnTagStartDefinition(getCurScope(), TagDecl); 2506bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 2507b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson SourceLocation FinalLoc; 2508b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson 2509b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson // Parse the optional 'final' keyword. 25104e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) { 25114e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith assert(isCXX11FinalKeyword() && "not a class definition"); 25128b11b5e6ce086fcaa7344bf84cffefcf4b53f9f6Richard Smith FinalLoc = ConsumeToken(); 2513b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson 2514e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall if (TagType == DeclSpec::TST_interface) { 2515e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall Diag(FinalLoc, diag::err_override_control_interface) 2516e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall << "final"; 2517e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall } else { 251880ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith Diag(FinalLoc, getLangOpts().CPlusPlus11 ? 2519e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall diag::warn_cxx98_compat_override_control_keyword : 2520e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall diag::ext_override_control_keyword) << "final"; 2521e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall } 25222e39713a3d72c243a2bcd13cc8f5036ba6b487d9Michael Han 252307fc1ba7553f2f5bf26984091197311decd9028eMichael Han // Parse any C++11 attributes after 'final' keyword. 252407fc1ba7553f2f5bf26984091197311decd9028eMichael Han // These attributes are not allowed to appear here, 252507fc1ba7553f2f5bf26984091197311decd9028eMichael Han // and the only possible place for them to appertain 252607fc1ba7553f2f5bf26984091197311decd9028eMichael Han // to the class would be between class-key and class-name. 2527053214013990ad8ec096dafc64aa7c0ad2b05bc0Richard Smith CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc); 2528b184a18a0a52e4bec33ef70f13bfcc29aafa14f2Anders Carlsson } 2529cc54d594d4f6509c0e3a8e349e481d9b5d899df6Anders Carlsson 2530bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall if (Tok.is(tok::colon)) { 2531bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall ParseBaseClause(TagDecl); 2532bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 2533bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall if (!Tok.is(tok::l_brace)) { 2534bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall Diag(Tok, diag::err_expected_lbrace_after_base_specifiers); 2535db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall 2536db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall if (TagDecl) 253723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnTagDefinitionError(getCurScope(), TagDecl); 2538bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall return; 2539bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall } 2540bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall } 2541bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 2542bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall assert(Tok.is(tok::l_brace)); 25434a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_brace); 25444a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 2545bd0dfa5c37d422427080a0ae3af9b63e70e6e854John McCall 254642a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall if (TagDecl) 25472c3ee54e51d835a35bbf781c69e17f39e2ba0480Anders Carlsson Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc, 25484a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getOpenLocation()); 2549f9368159334ff86ea5fa367225c1a580977f3b03John McCall 25504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // C++ 11p3: Members of a class defined with the keyword class are private 25514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // by default. Members of a class defined with the keywords struct or union 25524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // are public by default. 25534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis AccessSpecifier CurAS; 25544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (TagType == DeclSpec::TST_class) 25554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS_private; 25564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis else 25574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis CurAS = AS_public; 25585f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParsedAttributes AccessAttrs(AttrFactory); 25594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 256007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (TagDecl) { 256107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // While we still have something to read, read the member-declarations. 256207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 256307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Each iteration of this loop reads one member-declaration. 256407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor 25654e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) || 2566563a645de82231a55e221fe655b7188bf8369662Francois Pichet Tok.is(tok::kw___if_not_exists))) { 2567563a645de82231a55e221fe655b7188bf8369662Francois Pichet ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS); 2568563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 2569563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 2570563a645de82231a55e221fe655b7188bf8369662Francois Pichet 257107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Check for extraneous top-level semicolon. 257207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (Tok.is(tok::semi)) { 2573eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith ConsumeExtraSemi(InsideStruct, TagType); 257407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor continue; 257507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } 25761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2577aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman if (Tok.is(tok::annot_pragma_vis)) { 2578aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman HandlePragmaVisibility(); 2579aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman continue; 2580aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman } 2581aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman 2582aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman if (Tok.is(tok::annot_pragma_pack)) { 2583aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman HandlePragmaPack(); 2584aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman continue; 2585aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman } 2586aa5ab26ed93382b812147f532dcbf4afb5494040Eli Friedman 2587f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis if (Tok.is(tok::annot_pragma_align)) { 2588f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis HandlePragmaAlign(); 2589f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis continue; 2590f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis } 2591f4deaef8b816bd43258c30fe8e657ab041b675adArgyrios Kyrtzidis 2592c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev if (Tok.is(tok::annot_pragma_openmp)) { 2593c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev ParseOpenMPDeclarativeDirective(); 2594c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev continue; 2595c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev } 2596c640058aa7f224a71ce3b1d2601d84e1b57f82d3Alexey Bataev 259707976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor AccessSpecifier AS = getAccessSpecifierIfPresent(); 259807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (AS != AS_none) { 259907976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Current token is a C++ access specifier. 260007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor CurAS = AS; 260107976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor SourceLocation ASLoc = Tok.getLocation(); 260213f8daf70637f8f295134ac8e089dd7721e09085David Blaikie unsigned TokLength = Tok.getLength(); 260307976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor ConsumeToken(); 26045f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen AccessAttrs.clear(); 26055f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen MaybeParseGNUAttributes(AccessAttrs); 26065f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen 260713f8daf70637f8f295134ac8e089dd7721e09085David Blaikie SourceLocation EndLoc; 260813f8daf70637f8f295134ac8e089dd7721e09085David Blaikie if (Tok.is(tok::colon)) { 260913f8daf70637f8f295134ac8e089dd7721e09085David Blaikie EndLoc = Tok.getLocation(); 261013f8daf70637f8f295134ac8e089dd7721e09085David Blaikie ConsumeToken(); 261113f8daf70637f8f295134ac8e089dd7721e09085David Blaikie } else if (Tok.is(tok::semi)) { 261213f8daf70637f8f295134ac8e089dd7721e09085David Blaikie EndLoc = Tok.getLocation(); 261313f8daf70637f8f295134ac8e089dd7721e09085David Blaikie ConsumeToken(); 261413f8daf70637f8f295134ac8e089dd7721e09085David Blaikie Diag(EndLoc, diag::err_expected_colon) 261513f8daf70637f8f295134ac8e089dd7721e09085David Blaikie << FixItHint::CreateReplacement(EndLoc, ":"); 261613f8daf70637f8f295134ac8e089dd7721e09085David Blaikie } else { 261713f8daf70637f8f295134ac8e089dd7721e09085David Blaikie EndLoc = ASLoc.getLocWithOffset(TokLength); 261813f8daf70637f8f295134ac8e089dd7721e09085David Blaikie Diag(EndLoc, diag::err_expected_colon) 261913f8daf70637f8f295134ac8e089dd7721e09085David Blaikie << FixItHint::CreateInsertion(EndLoc, ":"); 262013f8daf70637f8f295134ac8e089dd7721e09085David Blaikie } 2621c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen 2622e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall // The Microsoft extension __interface does not permit non-public 2623e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall // access specifiers. 2624e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall if (TagType == DeclSpec::TST_interface && CurAS != AS_public) { 2625e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall Diag(ASLoc, diag::err_access_specifier_interface) 2626e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall << (CurAS == AS_protected); 2627e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall } 2628e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall 2629c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen if (Actions.ActOnAccessSpecifier(AS, ASLoc, EndLoc, 2630c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen AccessAttrs.getList())) { 2631c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen // found another attribute than only annotations 2632c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen AccessAttrs.clear(); 2633c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen } 2634c35cba4a54106117a52b267c7040b3bea9a4d18eErik Verbruggen 263507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor continue; 263607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } 26374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 263807976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // FIXME: Make sure we don't have a template here. 26394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 264007976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor // Parse all the comma separated declarators. 26415f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParseCXXClassMemberDeclaration(CurAS, AccessAttrs.getList()); 264207976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } 26431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26444a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 264507976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor } else { 264607976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor SkipUntil(tok::r_brace, false, false); 26474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 26481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 26494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If attributes exist after class contents, parse them. 26500b7e678a11ece4288dc01aebb5b17e5eef8f8d2dJohn McCall ParsedAttributes attrs(AttrFactory); 26517f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall MaybeParseGNUAttributes(attrs); 26524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 265342a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall if (TagDecl) 265423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl, 26554a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getOpenLocation(), 26564a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation(), 26577f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall attrs.getList()); 26584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 265974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // C++11 [class.mem]p2: 266074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // Within the class member-specification, the class is regarded as complete 2661a058fd4f0a944174295f77169b438510dad389f8Richard Smith // within function bodies, default arguments, and 266274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // brace-or-equal-initializers for non-static data members (including such 266374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor // things in nested classes). 266407976d25eda0fed2734518be022ee84fab898cc6Douglas Gregor if (TagDecl && NonNestedClass) { 26654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // We are not inside a nested class. This class and its nested classes 266672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // are complete and we can parse the delayed portions of method 2667eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // declarations and the lexed inline method definitions, along with any 2668eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski // delayed attributes. 2669e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor SourceLocation SavedPrevTokLocation = PrevTokLocation; 2670eff98fc3561f6b717f6348f04b3f4fe03e934466Caitlin Sadowski ParseLexedAttributes(getCurrentClass()); 26716569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseLexedMethodDeclarations(getCurrentClass()); 2672a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith 2673a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith // We've finished with all pending member declarations. 2674a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith Actions.ActOnFinishCXXMemberDecls(); 2675a4156b8574666aa69a2b0ad35dc9e9603433e4aeRichard Smith 26767a614d8380297fcd2bc23986241905d97222948cRichard Smith ParseLexedMemberInitializers(getCurrentClass()); 26776569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseLexedMethodDefs(getCurrentClass()); 2678e0cc047b1984fc301bbe6e98b6d197bed39ad562Douglas Gregor PrevTokLocation = SavedPrevTokLocation; 26794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 26804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 268142a4f66ffeb26e69b2f0ec873a5d41b0e39e634cJohn McCall if (TagDecl) 26824a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, 26834a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.getCloseLocation()); 2684db7bb4a4e7d9744cbc994c90932e6f056228e1ffJohn McCall 26854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Leave the class scope. 26866569d68745c8213709740337d2be52b031384f58Douglas Gregor ParsingDef.Pop(); 26878935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ClassScope.Exit(); 26884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 26897ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 26907ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer - Parse a C++ constructor initializer, 26917ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// which explicitly initializes the members or base classes of a 26927ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class (C++ [class.base.init]). For example, the three initializers 26937ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// after the ':' in the Derived constructor below: 26947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 26957ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @code 26967ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Base { }; 26977ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// class Derived : Base { 26987ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// int x; 26997ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// float f; 27007ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// public: 27017ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// Derived(float f) : Base(), x(17), f(f) { } 27027ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// }; 27037ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// @endcode 27047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 27051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++] ctor-initializer: 27061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// ':' mem-initializer-list 27077ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 27081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// [C++] mem-initializer-list: 27093fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor/// mem-initializer ...[opt] 27103fb9e4b89f72823f162096086f0f964e6dcf66d6Douglas Gregor/// mem-initializer ...[opt] , mem-initializer-list 2711d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallvoid Parser::ParseConstructorInitializer(Decl *ConstructorDecl) { 27127ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'"); 27137ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 271428bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley // Poison the SEH identifiers so they are flagged as illegal in constructor initializers 271528bbe4b8acc338476fe0825769b41fb32b423c72John Wiegley PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true); 27167ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SourceLocation ColonLoc = ConsumeToken(); 27171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27185f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<CXXCtorInitializer*, 4> MemInitializers; 27199db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor bool AnyErrors = false; 2720193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 27217ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor do { 27220133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor if (Tok.is(tok::code_completion)) { 2723572cf585da655522651b589101784c58902f8690Dmitri Gribenko Actions.CodeCompleteConstructorInitializer(ConstructorDecl, 2724572cf585da655522651b589101784c58902f8690Dmitri Gribenko MemInitializers); 27257d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis return cutOffParsing(); 27260133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor } else { 27270133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); 27280133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor if (!MemInit.isInvalid()) 27290133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor MemInitializers.push_back(MemInit.get()); 27300133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor else 27310133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor AnyErrors = true; 27320133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor } 27330133f525a23e18dd444880f7554f25fbcbd834e5Douglas Gregor 27347ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.is(tok::comma)) 27357ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor ConsumeToken(); 27367ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor else if (Tok.is(tok::l_brace)) 27377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor break; 2738b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor // If the next token looks like a base or member initializer, assume that 2739b1f6fa48960eae269a3931d1fc545ed468d9a4d2Douglas Gregor // we're just missing a comma. 2740751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor else if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) { 2741751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation); 2742751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor Diag(Loc, diag::err_ctor_init_missing_comma) 2743751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor << FixItHint::CreateInsertion(Loc, ", "); 2744751f6922376dfe9432795b65a3649179e4ef5cf5Douglas Gregor } else { 27457ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Skip over garbage, until we get to '{'. Don't eat the '{'. 2746d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma); 27477ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor SkipUntil(tok::l_brace, true, true); 27487ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor break; 27497ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 27507ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } while (true); 27517ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 275293c8617bec98aeb769ee9f569d7ed439eec03249David Blaikie Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, MemInitializers, 27539db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor AnyErrors); 27547ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor} 27557ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 27567ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseMemInitializer - Parse a C++ member initializer, which is 27577ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// part of a constructor initializer that explicitly initializes one 27587ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// member or base class (C++ [class.base.init]). See 27597ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// ParseConstructorInitializer for an example. 27607ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// 27617ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer: 27627ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// mem-initializer-id '(' expression-list[opt] ')' 2763dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl/// [C++0x] mem-initializer-id braced-init-list 27641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 27657ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// [C++] mem-initializer-id: 27667ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// '::'[opt] nested-name-specifier[opt] class-name 27677ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor/// identifier 2768d226f65006733ed7f709c3174f22ce33391cb58fJohn McCallParser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) { 2769bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian // parse '::'[opt] nested-name-specifier[opt] 2770bcfad54a43e5570e09daddd976bd4545933e75b1Fariborz Jahanian CXXScopeSpec SS; 2771efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); 2772b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall ParsedType TemplateTypeTy; 2773961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian if (Tok.is(tok::annot_template_id)) { 277425a767651d14db87aa03dd5fe3e011d877dd4100Argyrios Kyrtzidis TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 2775d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor if (TemplateId->Kind == TNK_Type_template || 2776d9b600c1a589200be905c53e2e10fceb57efa18dDouglas Gregor TemplateId->Kind == TNK_Dependent_template_name) { 2777059101f922de6eb765601459925f4c8914420b23Douglas Gregor AnnotateTemplateIdTokenAsType(); 2778961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); 2779b3d8748e797c6c2f1dc01186c8eeb3b1b5fe970cJohn McCall TemplateTypeTy = getTypeAnnotation(Tok); 2780961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian } 2781961743326fd18776f897bf4461345dba680ef637Fariborz Jahanian } 2782f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // Uses of decltype will already have been converted to annot_decltype by 2783f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // ParseOptionalCXXScopeSpecifier at this point. 2784f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie if (!TemplateTypeTy && Tok.isNot(tok::identifier) 2785f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie && Tok.isNot(tok::annot_decltype)) { 27861ab3b96de160e4fbffec2a776e284a48a3bb543dChris Lattner Diag(Tok, diag::err_expected_member_or_base_name); 27877ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor return true; 27887ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 27891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2790f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie IdentifierInfo *II = 0; 2791f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie DeclSpec DS(AttrFactory); 2792f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie SourceLocation IdLoc = Tok.getLocation(); 2793f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie if (Tok.is(tok::annot_decltype)) { 2794f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // Get the decltype expression, if there is one. 2795f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie ParseDecltypeSpecifier(DS); 2796f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie } else { 2797f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie if (Tok.is(tok::identifier)) 2798f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // Get the identifier. This may be a member name or a class name, 2799f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie // but we'll let the semantic analysis determine which it is. 2800f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie II = Tok.getIdentifierInfo(); 2801f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie ConsumeToken(); 2802f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie } 2803f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie 28047ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 28057ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Parse the '('. 280680ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 28077fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 28087fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 28096df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl ExprResult InitList = ParseBraceInitializer(); 28106df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl if (InitList.isInvalid()) 28116df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl return true; 28126df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl 28136df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl SourceLocation EllipsisLoc; 28146df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl if (Tok.is(tok::ellipsis)) 28156df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl EllipsisLoc = ConsumeToken(); 28166df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl 28176df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II, 2818f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie TemplateTypeTy, DS, IdLoc, 2819f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie InitList.take(), EllipsisLoc); 2820dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } else if(Tok.is(tok::l_paren)) { 28214a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 28224a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 2823dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl 2824dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl // Parse the optional expression-list. 28254e28d9e2ba9ce237549b45cfd4136ec6536d1325Benjamin Kramer ExprVector ArgExprs; 2826dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl CommaLocsTy CommaLocs; 2827dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) { 2828dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl SkipUntil(tok::r_paren); 2829dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return true; 2830dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } 28317ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 28324a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 28337ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 2834dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl SourceLocation EllipsisLoc; 2835dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl if (Tok.is(tok::ellipsis)) 2836dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl EllipsisLoc = ConsumeToken(); 28377ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor 2838dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II, 2839f211662199c87461f3b1475a549ab439c63ca83bDavid Blaikie TemplateTypeTy, DS, IdLoc, 2840a36bbac10f7b74ef198ec2fb0eb52dbd8a50e7f0Dmitri Gribenko T.getOpenLocation(), ArgExprs, 2841a36bbac10f7b74ef198ec2fb0eb52dbd8a50e7f0Dmitri Gribenko T.getCloseLocation(), EllipsisLoc); 2842dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl } 2843dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl 284480ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith Diag(Tok, getLangOpts().CPlusPlus11 ? diag::err_expected_lparen_or_lbrace 2845dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl : diag::err_expected_lparen); 2846dbef1bb8a8118b7b73e184e08fccfe0eaf914ddaSebastian Redl return true; 28477ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor} 28480fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 28497acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// \brief Parse a C++ exception-specification if present (C++0x [except.spec]). 28500fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 2851a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// exception-specification: 28527acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification 28537acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// noexcept-specification 28547acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 28557acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// noexcept-specification: 28567acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 'noexcept' 28577acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 'noexcept' '(' constant-expression ')' 28587acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType 2859a058fd4f0a944174295f77169b438510dad389f8Richard SmithParser::tryParseExceptionSpecification( 286074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor SourceRange &SpecificationRange, 28615f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<ParsedType> &DynamicExceptions, 28625f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<SourceRange> &DynamicExceptionRanges, 2863a058fd4f0a944174295f77169b438510dad389f8Richard Smith ExprResult &NoexceptExpr) { 28647acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl ExceptionSpecificationType Result = EST_None; 2865a058fd4f0a944174295f77169b438510dad389f8Richard Smith 28667acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // See if there's a dynamic specification. 28677acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.is(tok::kw_throw)) { 28687acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Result = ParseDynamicExceptionSpecification(SpecificationRange, 28697acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl DynamicExceptions, 28707acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl DynamicExceptionRanges); 28717acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl assert(DynamicExceptions.size() == DynamicExceptionRanges.size() && 28727acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl "Produced different number of exception types and ranges."); 28737acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 28747acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 28757acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // If there's no noexcept specification, we're done. 28767acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.isNot(tok::kw_noexcept)) 28777acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl return Result; 28787acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 2879841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith Diag(Tok, diag::warn_cxx98_compat_noexcept_decl); 2880841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith 28817acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // If we already had a dynamic specification, parse the noexcept for, 28827acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // recovery, but emit a diagnostic and don't store the results. 28837acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SourceRange NoexceptRange; 28847acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl ExceptionSpecificationType NoexceptType = EST_None; 28857acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 28867acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SourceLocation KeywordLoc = ConsumeToken(); 28877acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.is(tok::l_paren)) { 28887acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // There is an argument. 28894a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 28904a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeOpen(); 28917acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptType = EST_ComputedNoexcept; 28927acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptExpr = ParseConstantExpression(); 289360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // The argument must be contextually convertible to bool. We use 289460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // ActOnBooleanCondition for this purpose. 289560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (!NoexceptExpr.isInvalid()) 289660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NoexceptExpr = Actions.ActOnBooleanCondition(getCurScope(), KeywordLoc, 289760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NoexceptExpr.get()); 28984a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 28994a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation()); 29007acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } else { 29017acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // There is no argument. 29027acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptType = EST_BasicNoexcept; 29037acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl NoexceptRange = SourceRange(KeywordLoc, KeywordLoc); 29047acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 29057acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 29067acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Result == EST_None) { 29077acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SpecificationRange = NoexceptRange; 29087acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Result = NoexceptType; 29097acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 29107acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // If there's a dynamic specification after a noexcept specification, 29117acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl // parse that and ignore the results. 29127acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl if (Tok.is(tok::kw_throw)) { 29137acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification); 29147acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions, 29157acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl DynamicExceptionRanges); 29167acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 29177acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } else { 29187acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification); 29197acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl } 29207acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 29217acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl return Result; 29227acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl} 29237acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 292479f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smithstatic void diagnoseDynamicExceptionSpecification( 292579f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith Parser &P, const SourceRange &Range, bool IsNoexcept) { 292679f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith if (P.getLangOpts().CPlusPlus11) { 292779f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith const char *Replacement = IsNoexcept ? "noexcept" : "noexcept(false)"; 292879f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith P.Diag(Range.getBegin(), diag::warn_exception_spec_deprecated) << Range; 292979f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith P.Diag(Range.getBegin(), diag::note_exception_spec_deprecated) 293079f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith << Replacement << FixItHint::CreateReplacement(Range, Replacement); 293179f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith } 293279f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith} 293379f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith 29347acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// ParseDynamicExceptionSpecification - Parse a C++ 29357acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification (C++ [except.spec]). 29367acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// 29377acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl/// dynamic-exception-specification: 2938a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// 'throw' '(' type-id-list [opt] ')' 2939a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// [MS] 'throw' '(' '...' ')' 29401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// 2941a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor/// type-id-list: 2942a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor/// type-id ... [opt] 2943a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor/// type-id-list ',' type-id ... [opt] 29440fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor/// 29457acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian RedlExceptionSpecificationType Parser::ParseDynamicExceptionSpecification( 29467acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SourceRange &SpecificationRange, 29475f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<ParsedType> &Exceptions, 29485f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<SourceRange> &Ranges) { 29490fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor assert(Tok.is(tok::kw_throw) && "expected throw"); 29501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 29517acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SpecificationRange.setBegin(ConsumeToken()); 29524a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor BalancedDelimiterTracker T(*this, tok::l_paren); 29534a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor if (T.consumeOpen()) { 29547acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Diag(Tok, diag::err_expected_lparen_after) << "throw"; 29557acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl SpecificationRange.setEnd(SpecificationRange.getBegin()); 295660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return EST_DynamicNone; 29570fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor } 29580fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 2959a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor // Parse throw(...), a Microsoft extension that means "this function 2960a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor // can throw anything". 2961a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor if (Tok.is(tok::ellipsis)) { 2962a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor SourceLocation EllipsisLoc = ConsumeToken(); 29634e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().MicrosoftExt) 2964a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec); 29654a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 29664a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SpecificationRange.setEnd(T.getCloseLocation()); 296779f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith diagnoseDynamicExceptionSpecification(*this, SpecificationRange, false); 296860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return EST_MSAny; 2969a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor } 2970a4745616ebe36ba7699f18618382e764aa8183a1Douglas Gregor 29710fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor // Parse the sequence of type-ids. 2972ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl SourceRange Range; 29730fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor while (Tok.isNot(tok::r_paren)) { 2974ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl TypeResult Res(ParseTypeName(&Range)); 29757acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 2976a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor if (Tok.is(tok::ellipsis)) { 2977a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor // C++0x [temp.variadic]p5: 2978a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor // - In a dynamic-exception-specification (15.4); the pattern is a 2979a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor // type-id. 2980a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor SourceLocation Ellipsis = ConsumeToken(); 29817acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl Range.setEnd(Ellipsis); 2982a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor if (!Res.isInvalid()) 2983a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor Res = Actions.ActOnPackExpansion(Res.get(), Ellipsis); 2984a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor } 29857acafd032e145dbdbbed9274ca57ec2c86b912bcSebastian Redl 2986ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl if (!Res.isInvalid()) { 29877dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl Exceptions.push_back(Res.get()); 2988ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl Ranges.push_back(Range); 2989ef65f06e8e440aec541442cfd73a8a836e9bc842Sebastian Redl } 2990a04426c5416f22df1078f6b31c1619de73c40b59Douglas Gregor 29910fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor if (Tok.is(tok::comma)) 29920fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor ConsumeToken(); 29937dc813462dd9fd3f6f4296f896a12de14264fef8Sebastian Redl else 29940fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor break; 29950fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor } 29960fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor 29974a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor T.consumeClose(); 29984a8dfb511e8f84b2e38b7a86d8ddf05ac1e1a41bDouglas Gregor SpecificationRange.setEnd(T.getCloseLocation()); 299979f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith diagnoseDynamicExceptionSpecification(*this, SpecificationRange, 300079f4bb7aad1b7c53f8a3bc43d89de0efdef8286dRichard Smith Exceptions.empty()); 300160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic; 30020fe7bea6fca9737c6c145aaa4a2ad3abe595782aDouglas Gregor} 30036569d68745c8213709740337d2be52b031384f58Douglas Gregor 3004dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// ParseTrailingReturnType - Parse a trailing return type on a new-style 3005dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor/// function declaration. 3006ae7902c4293d9de8b9591759513f0d075f45022aDouglas GregorTypeResult Parser::ParseTrailingReturnType(SourceRange &Range) { 3007dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor assert(Tok.is(tok::arrow) && "expected arrow"); 3008dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor 3009dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor ConsumeToken(); 3010dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor 30117796eb5643244f3134834253ce5ea89107ac21c1Richard Smith return ParseTypeName(&Range, Declarator::TrailingReturnContext); 3012dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor} 3013dab60ad68a3a98d687305941a3852e793705f945Douglas Gregor 30146569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief We have just started parsing the definition of a new class, 30156569d68745c8213709740337d2be52b031384f58Douglas Gregor/// so push that class onto our stack of classes that is currently 30166569d68745c8213709740337d2be52b031384f58Douglas Gregor/// being parsed. 3017eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallSema::ParsingClassState 3018e402e72273cde2a64fa6097c1fe93f500038675dJohn McCallParser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass, 3019e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall bool IsInterface) { 302026997fd58c9560584edd154618f2f2c15ee68af4Douglas Gregor assert((NonNestedClass || !ClassStack.empty()) && 30216569d68745c8213709740337d2be52b031384f58Douglas Gregor "Nested class without outer class"); 3022e402e72273cde2a64fa6097c1fe93f500038675dJohn McCall ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass, IsInterface)); 3023eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall return Actions.PushParsingClass(); 30246569d68745c8213709740337d2be52b031384f58Douglas Gregor} 30256569d68745c8213709740337d2be52b031384f58Douglas Gregor 30266569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Deallocate the given parsed class and all of its nested 30276569d68745c8213709740337d2be52b031384f58Douglas Gregor/// classes. 30286569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) { 3029d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I) 3030d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor delete Class->LateParsedDeclarations[I]; 30316569d68745c8213709740337d2be52b031384f58Douglas Gregor delete Class; 30326569d68745c8213709740337d2be52b031384f58Douglas Gregor} 30336569d68745c8213709740337d2be52b031384f58Douglas Gregor 30346569d68745c8213709740337d2be52b031384f58Douglas Gregor/// \brief Pop the top class of the stack of classes that are 30356569d68745c8213709740337d2be52b031384f58Douglas Gregor/// currently being parsed. 30366569d68745c8213709740337d2be52b031384f58Douglas Gregor/// 30376569d68745c8213709740337d2be52b031384f58Douglas Gregor/// This routine should be called when we have finished parsing the 30386569d68745c8213709740337d2be52b031384f58Douglas Gregor/// definition of a class, but have not yet popped the Scope 30396569d68745c8213709740337d2be52b031384f58Douglas Gregor/// associated with the class's definition. 3040eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallvoid Parser::PopParsingClass(Sema::ParsingClassState state) { 30416569d68745c8213709740337d2be52b031384f58Douglas Gregor assert(!ClassStack.empty() && "Mismatched push/pop for class parsing"); 30421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3043eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall Actions.PopParsingClass(state); 3044eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 30456569d68745c8213709740337d2be52b031384f58Douglas Gregor ParsingClass *Victim = ClassStack.top(); 30466569d68745c8213709740337d2be52b031384f58Douglas Gregor ClassStack.pop(); 30476569d68745c8213709740337d2be52b031384f58Douglas Gregor if (Victim->TopLevelClass) { 30486569d68745c8213709740337d2be52b031384f58Douglas Gregor // Deallocate all of the nested classes of this class, 30496569d68745c8213709740337d2be52b031384f58Douglas Gregor // recursively: we don't need to keep any of this information. 30506569d68745c8213709740337d2be52b031384f58Douglas Gregor DeallocateParsedClasses(Victim); 30516569d68745c8213709740337d2be52b031384f58Douglas Gregor return; 30521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 30536569d68745c8213709740337d2be52b031384f58Douglas Gregor assert(!ClassStack.empty() && "Missing top-level class?"); 30546569d68745c8213709740337d2be52b031384f58Douglas Gregor 3055d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (Victim->LateParsedDeclarations.empty()) { 30566569d68745c8213709740337d2be52b031384f58Douglas Gregor // The victim is a nested class, but we will not need to perform 30576569d68745c8213709740337d2be52b031384f58Douglas Gregor // any processing after the definition of this class since it has 30586569d68745c8213709740337d2be52b031384f58Douglas Gregor // no members whose handling was delayed. Therefore, we can just 30596569d68745c8213709740337d2be52b031384f58Douglas Gregor // remove this nested class. 3060d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor DeallocateParsedClasses(Victim); 30616569d68745c8213709740337d2be52b031384f58Douglas Gregor return; 30626569d68745c8213709740337d2be52b031384f58Douglas Gregor } 30636569d68745c8213709740337d2be52b031384f58Douglas Gregor 30646569d68745c8213709740337d2be52b031384f58Douglas Gregor // This nested class has some members that will need to be processed 30656569d68745c8213709740337d2be52b031384f58Douglas Gregor // after the top-level class is completely defined. Therefore, add 30666569d68745c8213709740337d2be52b031384f58Douglas Gregor // it to the list of nested classes within its parent. 306723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor assert(getCurScope()->isClassScope() && "Nested class outside of class scope?"); 3068d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ClassStack.top()->LateParsedDeclarations.push_back(new LateParsedClass(this, Victim)); 306923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Victim->TemplateScope = getCurScope()->getParent()->isTemplateParamScope(); 30706569d68745c8213709740337d2be52b031384f58Douglas Gregor} 3071bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 3072c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// \brief Try to parse an 'identifier' which appears within an attribute-token. 3073c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// 3074c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// \return the parsed identifier on success, and 0 if the next token is not an 3075c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute-token. 3076c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// 3077c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// C++11 [dcl.attr.grammar]p3: 3078c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// If a keyword or an alternative token that satisfies the syntactic 3079c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// requirements of an identifier is contained in an attribute-token, 3080c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// it is considered an identifier. 3081c56298d87a9df507805a548d7d515e8b511df2c0Richard SmithIdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(SourceLocation &Loc) { 3082c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith switch (Tok.getKind()) { 3083c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith default: 3084c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // Identifiers and keywords have identifier info attached. 3085c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (IdentifierInfo *II = Tok.getIdentifierInfo()) { 3086c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith Loc = ConsumeToken(); 3087c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith return II; 3088c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 3089c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith return 0; 3090c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 3091c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::ampamp: // 'and' 3092c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::pipe: // 'bitor' 3093c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::pipepipe: // 'or' 3094c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::caret: // 'xor' 3095c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::tilde: // 'compl' 3096c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::amp: // 'bitand' 3097c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::ampequal: // 'and_eq' 3098c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::pipeequal: // 'or_eq' 3099c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::caretequal: // 'xor_eq' 3100c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::exclaim: // 'not' 3101c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith case tok::exclaimequal: // 'not_eq' 3102c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // Alternative tokens do not have identifier info, but their spelling 3103c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // starts with an alphabetical character. 3104cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallString<8> SpellingBuf; 3105c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith StringRef Spelling = PP.getSpelling(Tok.getLocation(), SpellingBuf); 31063f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose if (isLetter(Spelling[0])) { 3107c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith Loc = ConsumeToken(); 31080eb7526cd2524af78fb9a2a2522045fb25fc3d27Benjamin Kramer return &PP.getIdentifierTable().get(Spelling); 3109c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 3110c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith return 0; 3111c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 3112c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith} 3113c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 31146880f492365cc4fa4c941aa83688635003ee7498Michael Hanstatic bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName, 31156880f492365cc4fa4c941aa83688635003ee7498Michael Han IdentifierInfo *ScopeName) { 31166880f492365cc4fa4c941aa83688635003ee7498Michael Han switch (AttributeList::getKind(AttrName, ScopeName, 31176880f492365cc4fa4c941aa83688635003ee7498Michael Han AttributeList::AS_CXX11)) { 31186880f492365cc4fa4c941aa83688635003ee7498Michael Han case AttributeList::AT_CarriesDependency: 31196880f492365cc4fa4c941aa83688635003ee7498Michael Han case AttributeList::AT_FallThrough: 3120cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith case AttributeList::AT_CXX11NoReturn: { 31216880f492365cc4fa4c941aa83688635003ee7498Michael Han return true; 31226880f492365cc4fa4c941aa83688635003ee7498Michael Han } 31236880f492365cc4fa4c941aa83688635003ee7498Michael Han 31246880f492365cc4fa4c941aa83688635003ee7498Michael Han default: 31256880f492365cc4fa4c941aa83688635003ee7498Michael Han return false; 31266880f492365cc4fa4c941aa83688635003ee7498Michael Han } 31276880f492365cc4fa4c941aa83688635003ee7498Michael Han} 31286880f492365cc4fa4c941aa83688635003ee7498Michael Han 3129c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier. Currently 31303497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// only parses standard attributes. 3131bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 31326ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-specifier: 3133bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '[' '[' attribute-list ']' ']' 313482d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne/// alignment-specifier 3135bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 31366ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-list: 3137bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute[opt] 3138bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-list ',' attribute[opt] 3139c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute '...' 3140c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith/// attribute-list ',' attribute '...' 3141bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 31426ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute: 3143bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-token attribute-argument-clause[opt] 3144bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 31456ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-token: 3146bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// identifier 3147bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-scoped-token 3148bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 31496ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-scoped-token: 3150bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// attribute-namespace '::' identifier 3151bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 31526ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-namespace: 3153bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// identifier 3154bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 31556ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] attribute-argument-clause: 3156bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '(' balanced-token-seq ')' 3157bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 31586ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] balanced-token-seq: 3159bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// balanced-token 3160bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// balanced-token-seq balanced-token 3161bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// 31626ee326af4e77e6f05973486097884d7431f2108dRichard Smith/// [C++11] balanced-token: 3163bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '(' balanced-token-seq ')' 3164bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '[' balanced-token-seq ']' 3165bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// '{' balanced-token-seq '}' 3166bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt/// any token but '(', ')', '[', ']', '{', or '}' 3167c56298d87a9df507805a548d7d515e8b511df2c0Richard Smithvoid Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs, 31683497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne SourceLocation *endLoc) { 316982d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne if (Tok.is(tok::kw_alignas)) { 317041be673e93ed225b45479557b20ff19b3082bae8Richard Smith Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas); 317182d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne ParseAlignmentSpecifier(attrs, endLoc); 317282d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne return; 317382d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne } 317482d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne 3175bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square) 31766ee326af4e77e6f05973486097884d7431f2108dRichard Smith && "Not a C++11 attribute list"); 3177bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 317841be673e93ed225b45479557b20ff19b3082bae8Richard Smith Diag(Tok.getLocation(), diag::warn_cxx98_compat_attribute); 317941be673e93ed225b45479557b20ff19b3082bae8Richard Smith 3180bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeBracket(); 3181bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeBracket(); 3182193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 3183cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith llvm::SmallDenseMap<IdentifierInfo*, SourceLocation, 4> SeenAttrs; 3184cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith 3185c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith while (Tok.isNot(tok::r_square)) { 3186bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // attribute not present 3187bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.is(tok::comma)) { 3188bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeToken(); 3189bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt continue; 3190bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 3191bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 3192c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith SourceLocation ScopeLoc, AttrLoc; 3193c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith IdentifierInfo *ScopeName = 0, *AttrName = 0; 3194c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 3195c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith AttrName = TryParseCXX11AttributeIdentifier(AttrLoc); 3196c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (!AttrName) 3197c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith // Break out to the "expected ']'" diagnostic. 3198c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith break; 3199193575455e00eca03fd7177f60e3f2e6263cb661Kovarththanan Rajaratnam 3200bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt // scoped attribute 3201bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (Tok.is(tok::coloncolon)) { 3202bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt ConsumeToken(); 3203bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 3204c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith ScopeName = AttrName; 3205c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith ScopeLoc = AttrLoc; 3206c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith 3207c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith AttrName = TryParseCXX11AttributeIdentifier(AttrLoc); 3208c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (!AttrName) { 3209bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt Diag(Tok.getLocation(), diag::err_expected_ident); 3210bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_square, tok::comma, true, true); 3211bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt continue; 3212bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 3213bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 3214bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 32156880f492365cc4fa4c941aa83688635003ee7498Michael Han bool StandardAttr = IsBuiltInOrStandardCXX11Attribute(AttrName,ScopeName); 3216bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt bool AttrParsed = false; 32176880f492365cc4fa4c941aa83688635003ee7498Michael Han 3218cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith if (StandardAttr && 3219cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith !SeenAttrs.insert(std::make_pair(AttrName, AttrLoc)).second) 3220cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith Diag(AttrLoc, diag::err_cxx11_attribute_repeated) 3221cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith << AttrName << SourceRange(SeenAttrs[AttrName]); 3222cd8ab51a44e80625d84126780b0d85a7732e25afRichard Smith 32236880f492365cc4fa4c941aa83688635003ee7498Michael Han // Parse attribute arguments 32246880f492365cc4fa4c941aa83688635003ee7498Michael Han if (Tok.is(tok::l_paren)) { 32256880f492365cc4fa4c941aa83688635003ee7498Michael Han if (ScopeName && ScopeName->getName() == "gnu") { 32266880f492365cc4fa4c941aa83688635003ee7498Michael Han ParseGNUAttributeArgs(AttrName, AttrLoc, attrs, endLoc, 32276880f492365cc4fa4c941aa83688635003ee7498Michael Han ScopeName, ScopeLoc, AttributeList::AS_CXX11); 32286880f492365cc4fa4c941aa83688635003ee7498Michael Han AttrParsed = true; 32296880f492365cc4fa4c941aa83688635003ee7498Michael Han } else { 32306880f492365cc4fa4c941aa83688635003ee7498Michael Han if (StandardAttr) 32316880f492365cc4fa4c941aa83688635003ee7498Michael Han Diag(Tok.getLocation(), diag::err_cxx11_attribute_forbids_arguments) 32326880f492365cc4fa4c941aa83688635003ee7498Michael Han << AttrName->getName(); 32336880f492365cc4fa4c941aa83688635003ee7498Michael Han 32346880f492365cc4fa4c941aa83688635003ee7498Michael Han // FIXME: handle other formats of c++11 attribute arguments 32356880f492365cc4fa4c941aa83688635003ee7498Michael Han ConsumeParen(); 32366880f492365cc4fa4c941aa83688635003ee7498Michael Han SkipUntil(tok::r_paren, false); 3237bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 32386880f492365cc4fa4c941aa83688635003ee7498Michael Han } 3239bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 32406880f492365cc4fa4c941aa83688635003ee7498Michael Han if (!AttrParsed) 3241e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith attrs.addNew(AttrName, 3242e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc, 3243e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith AttrLoc), 3244e0d3b4cd2b66f1cef26cacbed5820ab7c22ad5b3Richard Smith ScopeName, ScopeLoc, 0, 324593f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt SourceLocation(), 0, 0, AttributeList::AS_CXX11); 32466ee326af4e77e6f05973486097884d7431f2108dRichard Smith 3247c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith if (Tok.is(tok::ellipsis)) { 32486ee326af4e77e6f05973486097884d7431f2108dRichard Smith ConsumeToken(); 32496880f492365cc4fa4c941aa83688635003ee7498Michael Han 32506880f492365cc4fa4c941aa83688635003ee7498Michael Han Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) 32516880f492365cc4fa4c941aa83688635003ee7498Michael Han << AttrName->getName(); 3252c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith } 3253bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt } 3254bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 3255bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare)) 3256bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_square, false); 32573497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne if (endLoc) 32583497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne *endLoc = Tok.getLocation(); 3259bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare)) 3260bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt SkipUntil(tok::r_square, false); 32613497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne} 32623497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne 32632edf0a2520313cde900799b1eb9bd11c9c776afeSean Hunt/// ParseCXX11Attributes - Parse a C++11 attribute-specifier-seq. 32643497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// 32653497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// attribute-specifier-seq: 32663497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne/// attribute-specifier-seq[opt] attribute-specifier 3267c56298d87a9df507805a548d7d515e8b511df2c0Richard Smithvoid Parser::ParseCXX11Attributes(ParsedAttributesWithRange &attrs, 32683497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne SourceLocation *endLoc) { 3269672edb0a04a5273e3a501f3b196844c125290780Richard Smith assert(getLangOpts().CPlusPlus11); 3270672edb0a04a5273e3a501f3b196844c125290780Richard Smith 32713497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne SourceLocation StartLoc = Tok.getLocation(), Loc; 32723497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne if (!endLoc) 32733497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne endLoc = &Loc; 32743497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne 32758828ee7faa42f889ade3bb635dc5f1338be671b1Douglas Gregor do { 3276c56298d87a9df507805a548d7d515e8b511df2c0Richard Smith ParseCXX11AttributeSpecifier(attrs, endLoc); 32776ee326af4e77e6f05973486097884d7431f2108dRichard Smith } while (isCXX11AttributeSpecifier()); 3278bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 32793497fdfdb742f55d7b7ec8e22779fb08962b8441Peter Collingbourne attrs.Range = SourceRange(StartLoc, *endLoc); 3280bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt} 3281bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt 3282334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ParseMicrosoftAttributes - Parse a Microsoft attribute [Attr] 3283334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// 3284334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute: 3285334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// '[' token-seq ']' 3286334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// 3287334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// [MS] ms-attribute-seq: 3288334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ms-attribute[opt] 3289334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet/// ms-attribute ms-attribute-seq 32907f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCallvoid Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs, 32917f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall SourceLocation *endLoc) { 3292334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list"); 3293334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet 3294334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet while (Tok.is(tok::l_square)) { 32956ee326af4e77e6f05973486097884d7431f2108dRichard Smith // FIXME: If this is actually a C++11 attribute, parse it as one. 3296334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet ConsumeBracket(); 3297334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet SkipUntil(tok::r_square, true, true); 32987f040a9d817cd1c72b565e92abff473510bf9e1dJohn McCall if (endLoc) *endLoc = Tok.getLocation(); 3299334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); 3300334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet } 3301334d47e92e9f241576fdeb7477b69a03136ba854Francois Pichet} 3302563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3303563a645de82231a55e221fe655b7188bf8369662Francois Pichetvoid Parser::ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType, 3304563a645de82231a55e221fe655b7188bf8369662Francois Pichet AccessSpecifier& CurAS) { 33053896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor IfExistsCondition Result; 3306563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (ParseMicrosoftIfExistsCondition(Result)) 3307563a645de82231a55e221fe655b7188bf8369662Francois Pichet return; 3308563a645de82231a55e221fe655b7188bf8369662Francois Pichet 33093896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor BalancedDelimiterTracker Braces(*this, tok::l_brace); 33103896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor if (Braces.consumeOpen()) { 3311563a645de82231a55e221fe655b7188bf8369662Francois Pichet Diag(Tok, diag::err_expected_lbrace); 3312563a645de82231a55e221fe655b7188bf8369662Francois Pichet return; 3313563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3314563a645de82231a55e221fe655b7188bf8369662Francois Pichet 33153896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor switch (Result.Behavior) { 33163896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor case IEB_Parse: 33173896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor // Parse the declarations below. 33183896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor break; 33193896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor 33203896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor case IEB_Dependent: 33213896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists) 33223896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor << Result.IsIfExists; 33233896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor // Fall through to skip. 33243896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor 33253896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor case IEB_Skip: 33263896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor Braces.skipToEnd(); 3327563a645de82231a55e221fe655b7188bf8369662Francois Pichet return; 3328563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3329563a645de82231a55e221fe655b7188bf8369662Francois Pichet 33303896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 3331563a645de82231a55e221fe655b7188bf8369662Francois Pichet // __if_exists, __if_not_exists can nest. 3332563a645de82231a55e221fe655b7188bf8369662Francois Pichet if ((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists))) { 3333563a645de82231a55e221fe655b7188bf8369662Francois Pichet ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS); 3334563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 3335563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3336563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3337563a645de82231a55e221fe655b7188bf8369662Francois Pichet // Check for extraneous top-level semicolon. 3338563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (Tok.is(tok::semi)) { 3339eab9d6f9065b042d39fbaf9842c9d8cc968dd6d0Richard Smith ConsumeExtraSemi(InsideStruct, TagType); 3340563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 3341563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3342563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3343563a645de82231a55e221fe655b7188bf8369662Francois Pichet AccessSpecifier AS = getAccessSpecifierIfPresent(); 3344563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (AS != AS_none) { 3345563a645de82231a55e221fe655b7188bf8369662Francois Pichet // Current token is a C++ access specifier. 3346563a645de82231a55e221fe655b7188bf8369662Francois Pichet CurAS = AS; 3347563a645de82231a55e221fe655b7188bf8369662Francois Pichet SourceLocation ASLoc = Tok.getLocation(); 3348563a645de82231a55e221fe655b7188bf8369662Francois Pichet ConsumeToken(); 3349563a645de82231a55e221fe655b7188bf8369662Francois Pichet if (Tok.is(tok::colon)) 3350563a645de82231a55e221fe655b7188bf8369662Francois Pichet Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation()); 3351563a645de82231a55e221fe655b7188bf8369662Francois Pichet else 3352563a645de82231a55e221fe655b7188bf8369662Francois Pichet Diag(Tok, diag::err_expected_colon); 3353563a645de82231a55e221fe655b7188bf8369662Francois Pichet ConsumeToken(); 3354563a645de82231a55e221fe655b7188bf8369662Francois Pichet continue; 3355563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 3356563a645de82231a55e221fe655b7188bf8369662Francois Pichet 3357563a645de82231a55e221fe655b7188bf8369662Francois Pichet // Parse all the comma separated declarators. 33585f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen ParseCXXClassMemberDeclaration(CurAS, 0); 3359563a645de82231a55e221fe655b7188bf8369662Francois Pichet } 33603896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor 33613896fc5d4daaf003e451e797e37de57dd8cf9cd5Douglas Gregor Braces.consumeClose(); 3362563a645de82231a55e221fe655b7188bf8369662Francois Pichet} 3363