ParseExprCXX.cpp revision 204643
1193326Sed//===--- ParseExprCXX.cpp - C++ Expression Parsing ------------------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements the Expression parsing implementation for C++. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#include "clang/Parse/ParseDiagnostic.h" 15193326Sed#include "clang/Parse/Parser.h" 16193326Sed#include "clang/Parse/DeclSpec.h" 17199482Srdivacky#include "clang/Parse/Template.h" 18198893Srdivacky#include "llvm/Support/ErrorHandling.h" 19198893Srdivacky 20193326Sedusing namespace clang; 21193326Sed 22198092Srdivacky/// \brief Parse global scope or nested-name-specifier if present. 23193326Sed/// 24198092Srdivacky/// Parses a C++ global scope specifier ('::') or nested-name-specifier (which 25198092Srdivacky/// may be preceded by '::'). Note that this routine will not parse ::new or 26198092Srdivacky/// ::delete; it will just leave them in the token stream. 27198092Srdivacky/// 28193326Sed/// '::'[opt] nested-name-specifier 29193326Sed/// '::' 30193326Sed/// 31193326Sed/// nested-name-specifier: 32193326Sed/// type-name '::' 33193326Sed/// namespace-name '::' 34193326Sed/// nested-name-specifier identifier '::' 35198092Srdivacky/// nested-name-specifier 'template'[opt] simple-template-id '::' 36193326Sed/// 37198092Srdivacky/// 38198092Srdivacky/// \param SS the scope specifier that will be set to the parsed 39198092Srdivacky/// nested-name-specifier (or empty) 40198092Srdivacky/// 41198092Srdivacky/// \param ObjectType if this nested-name-specifier is being parsed following 42198092Srdivacky/// the "." or "->" of a member access expression, this parameter provides the 43198092Srdivacky/// type of the object whose members are being accessed. 44198092Srdivacky/// 45198092Srdivacky/// \param EnteringContext whether we will be entering into the context of 46198092Srdivacky/// the nested-name-specifier after parsing it. 47198092Srdivacky/// 48204643Srdivacky/// \param MayBePseudoDestructor When non-NULL, points to a flag that 49204643Srdivacky/// indicates whether this nested-name-specifier may be part of a 50204643Srdivacky/// pseudo-destructor name. In this case, the flag will be set false 51204643Srdivacky/// if we don't actually end up parsing a destructor name. Moreorover, 52204643Srdivacky/// if we do end up determining that we are parsing a destructor name, 53204643Srdivacky/// the last component of the nested-name-specifier is not parsed as 54204643Srdivacky/// part of the scope specifier. 55204643Srdivacky 56204643Srdivacky/// member access expression, e.g., the \p T:: in \p p->T::m. 57204643Srdivacky/// 58204643Srdivacky/// \returns true if there was an error parsing a scope specifier 59198092Srdivackybool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, 60198092Srdivacky Action::TypeTy *ObjectType, 61204643Srdivacky bool EnteringContext, 62204643Srdivacky bool *MayBePseudoDestructor) { 63193326Sed assert(getLang().CPlusPlus && 64193326Sed "Call sites of this function should be guarded by checking for C++"); 65193326Sed 66193326Sed if (Tok.is(tok::annot_cxxscope)) { 67193326Sed SS.setScopeRep(Tok.getAnnotationValue()); 68193326Sed SS.setRange(Tok.getAnnotationRange()); 69193326Sed ConsumeToken(); 70204643Srdivacky return false; 71193326Sed } 72193326Sed 73193326Sed bool HasScopeSpecifier = false; 74193326Sed 75193326Sed if (Tok.is(tok::coloncolon)) { 76193326Sed // ::new and ::delete aren't nested-name-specifiers. 77193326Sed tok::TokenKind NextKind = NextToken().getKind(); 78193326Sed if (NextKind == tok::kw_new || NextKind == tok::kw_delete) 79193326Sed return false; 80198092Srdivacky 81193326Sed // '::' - Global scope qualifier. 82193326Sed SourceLocation CCLoc = ConsumeToken(); 83193326Sed SS.setBeginLoc(CCLoc); 84193326Sed SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc)); 85193326Sed SS.setEndLoc(CCLoc); 86193326Sed HasScopeSpecifier = true; 87193326Sed } 88193326Sed 89204643Srdivacky bool CheckForDestructor = false; 90204643Srdivacky if (MayBePseudoDestructor && *MayBePseudoDestructor) { 91204643Srdivacky CheckForDestructor = true; 92204643Srdivacky *MayBePseudoDestructor = false; 93204643Srdivacky } 94204643Srdivacky 95193326Sed while (true) { 96198092Srdivacky if (HasScopeSpecifier) { 97198092Srdivacky // C++ [basic.lookup.classref]p5: 98198092Srdivacky // If the qualified-id has the form 99198092Srdivacky // 100198092Srdivacky // ::class-name-or-namespace-name::... 101198092Srdivacky // 102198092Srdivacky // the class-name-or-namespace-name is looked up in global scope as a 103198092Srdivacky // class-name or namespace-name. 104198092Srdivacky // 105198092Srdivacky // To implement this, we clear out the object type as soon as we've 106198092Srdivacky // seen a leading '::' or part of a nested-name-specifier. 107198092Srdivacky ObjectType = 0; 108198092Srdivacky 109198092Srdivacky if (Tok.is(tok::code_completion)) { 110198092Srdivacky // Code completion for a nested-name-specifier, where the code 111198092Srdivacky // code completion token follows the '::'. 112198092Srdivacky Actions.CodeCompleteQualifiedId(CurScope, SS, EnteringContext); 113198092Srdivacky ConsumeToken(); 114198092Srdivacky } 115198092Srdivacky } 116198092Srdivacky 117193326Sed // nested-name-specifier: 118195099Sed // nested-name-specifier 'template'[opt] simple-template-id '::' 119195099Sed 120195099Sed // Parse the optional 'template' keyword, then make sure we have 121195099Sed // 'identifier <' after it. 122195099Sed if (Tok.is(tok::kw_template)) { 123198092Srdivacky // If we don't have a scope specifier or an object type, this isn't a 124198092Srdivacky // nested-name-specifier, since they aren't allowed to start with 125198092Srdivacky // 'template'. 126198092Srdivacky if (!HasScopeSpecifier && !ObjectType) 127198092Srdivacky break; 128198092Srdivacky 129199482Srdivacky TentativeParsingAction TPA(*this); 130195099Sed SourceLocation TemplateKWLoc = ConsumeToken(); 131198893Srdivacky 132198893Srdivacky UnqualifiedId TemplateName; 133198893Srdivacky if (Tok.is(tok::identifier)) { 134199482Srdivacky // Consume the identifier. 135198893Srdivacky TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 136198893Srdivacky ConsumeToken(); 137198893Srdivacky } else if (Tok.is(tok::kw_operator)) { 138198893Srdivacky if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, 139199482Srdivacky TemplateName)) { 140199482Srdivacky TPA.Commit(); 141198893Srdivacky break; 142199482Srdivacky } 143198893Srdivacky 144199990Srdivacky if (TemplateName.getKind() != UnqualifiedId::IK_OperatorFunctionId && 145199990Srdivacky TemplateName.getKind() != UnqualifiedId::IK_LiteralOperatorId) { 146198893Srdivacky Diag(TemplateName.getSourceRange().getBegin(), 147198893Srdivacky diag::err_id_after_template_in_nested_name_spec) 148198893Srdivacky << TemplateName.getSourceRange(); 149199482Srdivacky TPA.Commit(); 150198893Srdivacky break; 151198893Srdivacky } 152198893Srdivacky } else { 153199482Srdivacky TPA.Revert(); 154195099Sed break; 155193326Sed } 156198092Srdivacky 157199482Srdivacky // If the next token is not '<', we have a qualified-id that refers 158199482Srdivacky // to a template name, such as T::template apply, but is not a 159199482Srdivacky // template-id. 160199482Srdivacky if (Tok.isNot(tok::less)) { 161199482Srdivacky TPA.Revert(); 162199482Srdivacky break; 163199482Srdivacky } 164199482Srdivacky 165199482Srdivacky // Commit to parsing the template-id. 166199482Srdivacky TPA.Commit(); 167198092Srdivacky TemplateTy Template 168198893Srdivacky = Actions.ActOnDependentTemplateName(TemplateKWLoc, SS, TemplateName, 169199990Srdivacky ObjectType, EnteringContext); 170198092Srdivacky if (!Template) 171204643Srdivacky return true; 172195099Sed if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name, 173198893Srdivacky &SS, TemplateName, TemplateKWLoc, false)) 174204643Srdivacky return true; 175198092Srdivacky 176193326Sed continue; 177193326Sed } 178198092Srdivacky 179193326Sed if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) { 180198092Srdivacky // We have 181193326Sed // 182193326Sed // simple-template-id '::' 183193326Sed // 184193326Sed // So we need to check whether the simple-template-id is of the 185193326Sed // right kind (it should name a type or be dependent), and then 186193326Sed // convert it into a type within the nested-name-specifier. 187198092Srdivacky TemplateIdAnnotation *TemplateId 188193326Sed = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); 189204643Srdivacky if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) { 190204643Srdivacky *MayBePseudoDestructor = true; 191204643Srdivacky return false; 192204643Srdivacky } 193193326Sed 194198092Srdivacky if (TemplateId->Kind == TNK_Type_template || 195193326Sed TemplateId->Kind == TNK_Dependent_template_name) { 196193326Sed AnnotateTemplateIdTokenAsType(&SS); 197193326Sed 198198092Srdivacky assert(Tok.is(tok::annot_typename) && 199193326Sed "AnnotateTemplateIdTokenAsType isn't working"); 200193326Sed Token TypeToken = Tok; 201193326Sed ConsumeToken(); 202193326Sed assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!"); 203193326Sed SourceLocation CCLoc = ConsumeToken(); 204198092Srdivacky 205193326Sed if (!HasScopeSpecifier) { 206193326Sed SS.setBeginLoc(TypeToken.getLocation()); 207193326Sed HasScopeSpecifier = true; 208193326Sed } 209198092Srdivacky 210193326Sed if (TypeToken.getAnnotationValue()) 211193326Sed SS.setScopeRep( 212198092Srdivacky Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, 213193326Sed TypeToken.getAnnotationValue(), 214193326Sed TypeToken.getAnnotationRange(), 215193326Sed CCLoc)); 216193326Sed else 217193326Sed SS.setScopeRep(0); 218193326Sed SS.setEndLoc(CCLoc); 219193326Sed continue; 220195099Sed } 221198092Srdivacky 222195099Sed assert(false && "FIXME: Only type template names supported here"); 223193326Sed } 224193326Sed 225195099Sed 226195099Sed // The rest of the nested-name-specifier possibilities start with 227195099Sed // tok::identifier. 228195099Sed if (Tok.isNot(tok::identifier)) 229195099Sed break; 230195099Sed 231195099Sed IdentifierInfo &II = *Tok.getIdentifierInfo(); 232195099Sed 233195099Sed // nested-name-specifier: 234195099Sed // type-name '::' 235195099Sed // namespace-name '::' 236195099Sed // nested-name-specifier identifier '::' 237195099Sed Token Next = NextToken(); 238200583Srdivacky 239200583Srdivacky // If we get foo:bar, this is almost certainly a typo for foo::bar. Recover 240200583Srdivacky // and emit a fixit hint for it. 241204643Srdivacky if (Next.is(tok::colon) && !ColonIsSacred) { 242204643Srdivacky if (Actions.IsInvalidUnlessNestedName(CurScope, SS, II, ObjectType, 243204643Srdivacky EnteringContext) && 244204643Srdivacky // If the token after the colon isn't an identifier, it's still an 245204643Srdivacky // error, but they probably meant something else strange so don't 246204643Srdivacky // recover like this. 247204643Srdivacky PP.LookAhead(1).is(tok::identifier)) { 248204643Srdivacky Diag(Next, diag::err_unexected_colon_in_nested_name_spec) 249204643Srdivacky << CodeModificationHint::CreateReplacement(Next.getLocation(), "::"); 250204643Srdivacky 251204643Srdivacky // Recover as if the user wrote '::'. 252204643Srdivacky Next.setKind(tok::coloncolon); 253204643Srdivacky } 254200583Srdivacky } 255200583Srdivacky 256195099Sed if (Next.is(tok::coloncolon)) { 257204643Srdivacky if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde) && 258204643Srdivacky !Actions.isNonTypeNestedNameSpecifier(CurScope, SS, Tok.getLocation(), 259204643Srdivacky II, ObjectType)) { 260204643Srdivacky *MayBePseudoDestructor = true; 261204643Srdivacky return false; 262204643Srdivacky } 263204643Srdivacky 264195099Sed // We have an identifier followed by a '::'. Lookup this name 265195099Sed // as the name in a nested-name-specifier. 266195099Sed SourceLocation IdLoc = ConsumeToken(); 267200583Srdivacky assert((Tok.is(tok::coloncolon) || Tok.is(tok::colon)) && 268200583Srdivacky "NextToken() not working properly!"); 269195099Sed SourceLocation CCLoc = ConsumeToken(); 270198092Srdivacky 271195099Sed if (!HasScopeSpecifier) { 272195099Sed SS.setBeginLoc(IdLoc); 273195099Sed HasScopeSpecifier = true; 274195099Sed } 275198092Srdivacky 276195099Sed if (SS.isInvalid()) 277195099Sed continue; 278198092Srdivacky 279195099Sed SS.setScopeRep( 280198092Srdivacky Actions.ActOnCXXNestedNameSpecifier(CurScope, SS, IdLoc, CCLoc, II, 281198092Srdivacky ObjectType, EnteringContext)); 282195099Sed SS.setEndLoc(CCLoc); 283195099Sed continue; 284195099Sed } 285198092Srdivacky 286195099Sed // nested-name-specifier: 287195099Sed // type-name '<' 288195099Sed if (Next.is(tok::less)) { 289195099Sed TemplateTy Template; 290198893Srdivacky UnqualifiedId TemplateName; 291198893Srdivacky TemplateName.setIdentifier(&II, Tok.getLocation()); 292198893Srdivacky if (TemplateNameKind TNK = Actions.isTemplateName(CurScope, SS, 293198893Srdivacky TemplateName, 294198092Srdivacky ObjectType, 295198092Srdivacky EnteringContext, 296198092Srdivacky Template)) { 297195099Sed // We have found a template name, so annotate this this token 298195099Sed // with a template-id annotation. We do not permit the 299195099Sed // template-id to be translated into a type annotation, 300195099Sed // because some clients (e.g., the parsing of class template 301195099Sed // specializations) still want to see the original template-id 302195099Sed // token. 303198893Srdivacky ConsumeToken(); 304198893Srdivacky if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName, 305198893Srdivacky SourceLocation(), false)) 306204643Srdivacky return true; 307195099Sed continue; 308195099Sed } 309195099Sed } 310195099Sed 311193326Sed // We don't have any tokens that form the beginning of a 312193326Sed // nested-name-specifier, so we're done. 313193326Sed break; 314193326Sed } 315198092Srdivacky 316204643Srdivacky // Even if we didn't see any pieces of a nested-name-specifier, we 317204643Srdivacky // still check whether there is a tilde in this position, which 318204643Srdivacky // indicates a potential pseudo-destructor. 319204643Srdivacky if (CheckForDestructor && Tok.is(tok::tilde)) 320204643Srdivacky *MayBePseudoDestructor = true; 321204643Srdivacky 322204643Srdivacky return false; 323193326Sed} 324193326Sed 325193326Sed/// ParseCXXIdExpression - Handle id-expression. 326193326Sed/// 327193326Sed/// id-expression: 328193326Sed/// unqualified-id 329193326Sed/// qualified-id 330193326Sed/// 331193326Sed/// qualified-id: 332193326Sed/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 333193326Sed/// '::' identifier 334193326Sed/// '::' operator-function-id 335195341Sed/// '::' template-id 336193326Sed/// 337193326Sed/// NOTE: The standard specifies that, for qualified-id, the parser does not 338193326Sed/// expect: 339193326Sed/// 340193326Sed/// '::' conversion-function-id 341193326Sed/// '::' '~' class-name 342193326Sed/// 343193326Sed/// This may cause a slight inconsistency on diagnostics: 344193326Sed/// 345193326Sed/// class C {}; 346193326Sed/// namespace A {} 347193326Sed/// void f() { 348193326Sed/// :: A :: ~ C(); // Some Sema error about using destructor with a 349193326Sed/// // namespace. 350193326Sed/// :: ~ C(); // Some Parser error like 'unexpected ~'. 351193326Sed/// } 352193326Sed/// 353193326Sed/// We simplify the parser a bit and make it work like: 354193326Sed/// 355193326Sed/// qualified-id: 356193326Sed/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 357193326Sed/// '::' unqualified-id 358193326Sed/// 359193326Sed/// That way Sema can handle and report similar errors for namespaces and the 360193326Sed/// global scope. 361193326Sed/// 362193326Sed/// The isAddressOfOperand parameter indicates that this id-expression is a 363193326Sed/// direct operand of the address-of operator. This is, besides member contexts, 364193326Sed/// the only place where a qualified-id naming a non-static class member may 365193326Sed/// appear. 366193326Sed/// 367193326SedParser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { 368193326Sed // qualified-id: 369193326Sed // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id 370193326Sed // '::' unqualified-id 371193326Sed // 372193326Sed CXXScopeSpec SS; 373198092Srdivacky ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false); 374198893Srdivacky 375198893Srdivacky UnqualifiedId Name; 376198893Srdivacky if (ParseUnqualifiedId(SS, 377198893Srdivacky /*EnteringContext=*/false, 378198893Srdivacky /*AllowDestructorName=*/false, 379198893Srdivacky /*AllowConstructorName=*/false, 380198893Srdivacky /*ObjectType=*/0, 381198893Srdivacky Name)) 382193326Sed return ExprError(); 383199990Srdivacky 384199990Srdivacky // This is only the direct operand of an & operator if it is not 385199990Srdivacky // followed by a postfix-expression suffix. 386199990Srdivacky if (isAddressOfOperand) { 387199990Srdivacky switch (Tok.getKind()) { 388199990Srdivacky case tok::l_square: 389199990Srdivacky case tok::l_paren: 390199990Srdivacky case tok::arrow: 391199990Srdivacky case tok::period: 392199990Srdivacky case tok::plusplus: 393199990Srdivacky case tok::minusminus: 394199990Srdivacky isAddressOfOperand = false; 395199990Srdivacky break; 396199990Srdivacky 397199990Srdivacky default: 398199990Srdivacky break; 399199990Srdivacky } 400199990Srdivacky } 401198893Srdivacky 402198893Srdivacky return Actions.ActOnIdExpression(CurScope, SS, Name, Tok.is(tok::l_paren), 403198893Srdivacky isAddressOfOperand); 404198893Srdivacky 405193326Sed} 406193326Sed 407193326Sed/// ParseCXXCasts - This handles the various ways to cast expressions to another 408193326Sed/// type. 409193326Sed/// 410193326Sed/// postfix-expression: [C++ 5.2p1] 411193326Sed/// 'dynamic_cast' '<' type-name '>' '(' expression ')' 412193326Sed/// 'static_cast' '<' type-name '>' '(' expression ')' 413193326Sed/// 'reinterpret_cast' '<' type-name '>' '(' expression ')' 414193326Sed/// 'const_cast' '<' type-name '>' '(' expression ')' 415193326Sed/// 416193326SedParser::OwningExprResult Parser::ParseCXXCasts() { 417193326Sed tok::TokenKind Kind = Tok.getKind(); 418193326Sed const char *CastName = 0; // For error messages 419193326Sed 420193326Sed switch (Kind) { 421193326Sed default: assert(0 && "Unknown C++ cast!"); abort(); 422193326Sed case tok::kw_const_cast: CastName = "const_cast"; break; 423193326Sed case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break; 424193326Sed case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break; 425193326Sed case tok::kw_static_cast: CastName = "static_cast"; break; 426193326Sed } 427193326Sed 428193326Sed SourceLocation OpLoc = ConsumeToken(); 429193326Sed SourceLocation LAngleBracketLoc = Tok.getLocation(); 430193326Sed 431193326Sed if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName)) 432193326Sed return ExprError(); 433193326Sed 434193326Sed TypeResult CastTy = ParseTypeName(); 435193326Sed SourceLocation RAngleBracketLoc = Tok.getLocation(); 436193326Sed 437193326Sed if (ExpectAndConsume(tok::greater, diag::err_expected_greater)) 438193326Sed return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<"); 439193326Sed 440193326Sed SourceLocation LParenLoc = Tok.getLocation(), RParenLoc; 441193326Sed 442193326Sed if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, CastName)) 443193326Sed return ExprError(); 444193326Sed 445193326Sed OwningExprResult Result = ParseExpression(); 446198092Srdivacky 447193326Sed // Match the ')'. 448199482Srdivacky RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 449198092Srdivacky 450193326Sed if (!Result.isInvalid() && !CastTy.isInvalid()) 451193326Sed Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, 452193326Sed LAngleBracketLoc, CastTy.get(), 453193326Sed RAngleBracketLoc, 454193326Sed LParenLoc, move(Result), RParenLoc); 455193326Sed 456193326Sed return move(Result); 457193326Sed} 458193326Sed 459193326Sed/// ParseCXXTypeid - This handles the C++ typeid expression. 460193326Sed/// 461193326Sed/// postfix-expression: [C++ 5.2p1] 462193326Sed/// 'typeid' '(' expression ')' 463193326Sed/// 'typeid' '(' type-id ')' 464193326Sed/// 465193326SedParser::OwningExprResult Parser::ParseCXXTypeid() { 466193326Sed assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); 467193326Sed 468193326Sed SourceLocation OpLoc = ConsumeToken(); 469193326Sed SourceLocation LParenLoc = Tok.getLocation(); 470193326Sed SourceLocation RParenLoc; 471193326Sed 472193326Sed // typeid expressions are always parenthesized. 473193326Sed if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, 474193326Sed "typeid")) 475193326Sed return ExprError(); 476193326Sed 477193326Sed OwningExprResult Result(Actions); 478193326Sed 479193326Sed if (isTypeIdInParens()) { 480193326Sed TypeResult Ty = ParseTypeName(); 481193326Sed 482193326Sed // Match the ')'. 483193326Sed MatchRHSPunctuation(tok::r_paren, LParenLoc); 484193326Sed 485193326Sed if (Ty.isInvalid()) 486193326Sed return ExprError(); 487193326Sed 488193326Sed Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, 489193326Sed Ty.get(), RParenLoc); 490193326Sed } else { 491194613Sed // C++0x [expr.typeid]p3: 492198092Srdivacky // When typeid is applied to an expression other than an lvalue of a 493198092Srdivacky // polymorphic class type [...] The expression is an unevaluated 494194613Sed // operand (Clause 5). 495194613Sed // 496198092Srdivacky // Note that we can't tell whether the expression is an lvalue of a 497194613Sed // polymorphic class type until after we've parsed the expression, so 498194711Sed // we the expression is potentially potentially evaluated. 499194711Sed EnterExpressionEvaluationContext Unevaluated(Actions, 500194711Sed Action::PotentiallyPotentiallyEvaluated); 501193326Sed Result = ParseExpression(); 502193326Sed 503193326Sed // Match the ')'. 504193326Sed if (Result.isInvalid()) 505193326Sed SkipUntil(tok::r_paren); 506193326Sed else { 507193326Sed MatchRHSPunctuation(tok::r_paren, LParenLoc); 508193326Sed 509193326Sed Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false, 510193326Sed Result.release(), RParenLoc); 511193326Sed } 512193326Sed } 513193326Sed 514193326Sed return move(Result); 515193326Sed} 516193326Sed 517204643Srdivacky/// \brief Parse a C++ pseudo-destructor expression after the base, 518204643Srdivacky/// . or -> operator, and nested-name-specifier have already been 519204643Srdivacky/// parsed. 520204643Srdivacky/// 521204643Srdivacky/// postfix-expression: [C++ 5.2] 522204643Srdivacky/// postfix-expression . pseudo-destructor-name 523204643Srdivacky/// postfix-expression -> pseudo-destructor-name 524204643Srdivacky/// 525204643Srdivacky/// pseudo-destructor-name: 526204643Srdivacky/// ::[opt] nested-name-specifier[opt] type-name :: ~type-name 527204643Srdivacky/// ::[opt] nested-name-specifier template simple-template-id :: 528204643Srdivacky/// ~type-name 529204643Srdivacky/// ::[opt] nested-name-specifier[opt] ~type-name 530204643Srdivacky/// 531204643SrdivackyParser::OwningExprResult 532204643SrdivackyParser::ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc, 533204643Srdivacky tok::TokenKind OpKind, 534204643Srdivacky CXXScopeSpec &SS, 535204643Srdivacky Action::TypeTy *ObjectType) { 536204643Srdivacky // We're parsing either a pseudo-destructor-name or a dependent 537204643Srdivacky // member access that has the same form as a 538204643Srdivacky // pseudo-destructor-name. We parse both in the same way and let 539204643Srdivacky // the action model sort them out. 540204643Srdivacky // 541204643Srdivacky // Note that the ::[opt] nested-name-specifier[opt] has already 542204643Srdivacky // been parsed, and if there was a simple-template-id, it has 543204643Srdivacky // been coalesced into a template-id annotation token. 544204643Srdivacky UnqualifiedId FirstTypeName; 545204643Srdivacky SourceLocation CCLoc; 546204643Srdivacky if (Tok.is(tok::identifier)) { 547204643Srdivacky FirstTypeName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 548204643Srdivacky ConsumeToken(); 549204643Srdivacky assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail"); 550204643Srdivacky CCLoc = ConsumeToken(); 551204643Srdivacky } else if (Tok.is(tok::annot_template_id)) { 552204643Srdivacky FirstTypeName.setTemplateId( 553204643Srdivacky (TemplateIdAnnotation *)Tok.getAnnotationValue()); 554204643Srdivacky ConsumeToken(); 555204643Srdivacky assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail"); 556204643Srdivacky CCLoc = ConsumeToken(); 557204643Srdivacky } else { 558204643Srdivacky FirstTypeName.setIdentifier(0, SourceLocation()); 559204643Srdivacky } 560204643Srdivacky 561204643Srdivacky // Parse the tilde. 562204643Srdivacky assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail"); 563204643Srdivacky SourceLocation TildeLoc = ConsumeToken(); 564204643Srdivacky if (!Tok.is(tok::identifier)) { 565204643Srdivacky Diag(Tok, diag::err_destructor_tilde_identifier); 566204643Srdivacky return ExprError(); 567204643Srdivacky } 568204643Srdivacky 569204643Srdivacky // Parse the second type. 570204643Srdivacky UnqualifiedId SecondTypeName; 571204643Srdivacky IdentifierInfo *Name = Tok.getIdentifierInfo(); 572204643Srdivacky SourceLocation NameLoc = ConsumeToken(); 573204643Srdivacky SecondTypeName.setIdentifier(Name, NameLoc); 574204643Srdivacky 575204643Srdivacky // If there is a '<', the second type name is a template-id. Parse 576204643Srdivacky // it as such. 577204643Srdivacky if (Tok.is(tok::less) && 578204643Srdivacky ParseUnqualifiedIdTemplateId(SS, Name, NameLoc, false, ObjectType, 579204643Srdivacky SecondTypeName, /*AssumeTemplateName=*/true)) 580204643Srdivacky return ExprError(); 581204643Srdivacky 582204643Srdivacky return Actions.ActOnPseudoDestructorExpr(CurScope, move(Base), OpLoc, OpKind, 583204643Srdivacky SS, FirstTypeName, CCLoc, 584204643Srdivacky TildeLoc, SecondTypeName, 585204643Srdivacky Tok.is(tok::l_paren)); 586204643Srdivacky} 587204643Srdivacky 588193326Sed/// ParseCXXBoolLiteral - This handles the C++ Boolean literals. 589193326Sed/// 590193326Sed/// boolean-literal: [C++ 2.13.5] 591193326Sed/// 'true' 592193326Sed/// 'false' 593193326SedParser::OwningExprResult Parser::ParseCXXBoolLiteral() { 594193326Sed tok::TokenKind Kind = Tok.getKind(); 595193326Sed return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); 596193326Sed} 597193326Sed 598193326Sed/// ParseThrowExpression - This handles the C++ throw expression. 599193326Sed/// 600193326Sed/// throw-expression: [C++ 15] 601193326Sed/// 'throw' assignment-expression[opt] 602193326SedParser::OwningExprResult Parser::ParseThrowExpression() { 603193326Sed assert(Tok.is(tok::kw_throw) && "Not throw!"); 604193326Sed SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. 605193326Sed 606193326Sed // If the current token isn't the start of an assignment-expression, 607193326Sed // then the expression is not present. This handles things like: 608193326Sed // "C ? throw : (void)42", which is crazy but legal. 609193326Sed switch (Tok.getKind()) { // FIXME: move this predicate somewhere common. 610193326Sed case tok::semi: 611193326Sed case tok::r_paren: 612193326Sed case tok::r_square: 613193326Sed case tok::r_brace: 614193326Sed case tok::colon: 615193326Sed case tok::comma: 616193326Sed return Actions.ActOnCXXThrow(ThrowLoc, ExprArg(Actions)); 617193326Sed 618193326Sed default: 619193326Sed OwningExprResult Expr(ParseAssignmentExpression()); 620193326Sed if (Expr.isInvalid()) return move(Expr); 621193326Sed return Actions.ActOnCXXThrow(ThrowLoc, move(Expr)); 622193326Sed } 623193326Sed} 624193326Sed 625193326Sed/// ParseCXXThis - This handles the C++ 'this' pointer. 626193326Sed/// 627193326Sed/// C++ 9.3.2: In the body of a non-static member function, the keyword this is 628193326Sed/// a non-lvalue expression whose value is the address of the object for which 629193326Sed/// the function is called. 630193326SedParser::OwningExprResult Parser::ParseCXXThis() { 631193326Sed assert(Tok.is(tok::kw_this) && "Not 'this'!"); 632193326Sed SourceLocation ThisLoc = ConsumeToken(); 633193326Sed return Actions.ActOnCXXThis(ThisLoc); 634193326Sed} 635193326Sed 636193326Sed/// ParseCXXTypeConstructExpression - Parse construction of a specified type. 637193326Sed/// Can be interpreted either as function-style casting ("int(x)") 638193326Sed/// or class type construction ("ClassType(x,y,z)") 639193326Sed/// or creation of a value-initialized type ("int()"). 640193326Sed/// 641193326Sed/// postfix-expression: [C++ 5.2p1] 642193326Sed/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] 643193326Sed/// typename-specifier '(' expression-list[opt] ')' [TODO] 644193326Sed/// 645193326SedParser::OwningExprResult 646193326SedParser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { 647193326Sed Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 648193326Sed TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).get(); 649193326Sed 650193326Sed assert(Tok.is(tok::l_paren) && "Expected '('!"); 651193326Sed SourceLocation LParenLoc = ConsumeParen(); 652193326Sed 653193326Sed ExprVector Exprs(Actions); 654193326Sed CommaLocsTy CommaLocs; 655193326Sed 656193326Sed if (Tok.isNot(tok::r_paren)) { 657193326Sed if (ParseExpressionList(Exprs, CommaLocs)) { 658193326Sed SkipUntil(tok::r_paren); 659193326Sed return ExprError(); 660193326Sed } 661193326Sed } 662193326Sed 663193326Sed // Match the ')'. 664193326Sed SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 665193326Sed 666198092Srdivacky // TypeRep could be null, if it references an invalid typedef. 667198092Srdivacky if (!TypeRep) 668198092Srdivacky return ExprError(); 669198092Srdivacky 670193326Sed assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&& 671193326Sed "Unexpected number of commas!"); 672193326Sed return Actions.ActOnCXXTypeConstructExpr(DS.getSourceRange(), TypeRep, 673193326Sed LParenLoc, move_arg(Exprs), 674193326Sed CommaLocs.data(), RParenLoc); 675193326Sed} 676193326Sed 677199990Srdivacky/// ParseCXXCondition - if/switch/while condition expression. 678193326Sed/// 679193326Sed/// condition: 680193326Sed/// expression 681193326Sed/// type-specifier-seq declarator '=' assignment-expression 682193326Sed/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] 683193326Sed/// '=' assignment-expression 684193326Sed/// 685199990Srdivacky/// \param ExprResult if the condition was parsed as an expression, the 686199990Srdivacky/// parsed expression. 687199990Srdivacky/// 688199990Srdivacky/// \param DeclResult if the condition was parsed as a declaration, the 689199990Srdivacky/// parsed declaration. 690199990Srdivacky/// 691199990Srdivacky/// \returns true if there was a parsing, false otherwise. 692199990Srdivackybool Parser::ParseCXXCondition(OwningExprResult &ExprResult, 693199990Srdivacky DeclPtrTy &DeclResult) { 694202379Srdivacky if (Tok.is(tok::code_completion)) { 695202379Srdivacky Actions.CodeCompleteOrdinaryName(CurScope, Action::CCC_Condition); 696202379Srdivacky ConsumeToken(); 697202379Srdivacky } 698202379Srdivacky 699199990Srdivacky if (!isCXXConditionDeclaration()) { 700199990Srdivacky ExprResult = ParseExpression(); // expression 701199990Srdivacky DeclResult = DeclPtrTy(); 702199990Srdivacky return ExprResult.isInvalid(); 703199990Srdivacky } 704193326Sed 705193326Sed // type-specifier-seq 706193326Sed DeclSpec DS; 707193326Sed ParseSpecifierQualifierList(DS); 708193326Sed 709193326Sed // declarator 710193326Sed Declarator DeclaratorInfo(DS, Declarator::ConditionContext); 711193326Sed ParseDeclarator(DeclaratorInfo); 712193326Sed 713193326Sed // simple-asm-expr[opt] 714193326Sed if (Tok.is(tok::kw_asm)) { 715193326Sed SourceLocation Loc; 716193326Sed OwningExprResult AsmLabel(ParseSimpleAsm(&Loc)); 717193326Sed if (AsmLabel.isInvalid()) { 718193326Sed SkipUntil(tok::semi); 719199990Srdivacky return true; 720193326Sed } 721193326Sed DeclaratorInfo.setAsmLabel(AsmLabel.release()); 722193326Sed DeclaratorInfo.SetRangeEnd(Loc); 723193326Sed } 724193326Sed 725193326Sed // If attributes are present, parse them. 726193326Sed if (Tok.is(tok::kw___attribute)) { 727193326Sed SourceLocation Loc; 728199990Srdivacky AttributeList *AttrList = ParseGNUAttributes(&Loc); 729193326Sed DeclaratorInfo.AddAttributes(AttrList, Loc); 730193326Sed } 731193326Sed 732199990Srdivacky // Type-check the declaration itself. 733199990Srdivacky Action::DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(CurScope, 734199990Srdivacky DeclaratorInfo); 735199990Srdivacky DeclResult = Dcl.get(); 736199990Srdivacky ExprResult = ExprError(); 737199990Srdivacky 738193326Sed // '=' assignment-expression 739199990Srdivacky if (Tok.is(tok::equal)) { 740199990Srdivacky SourceLocation EqualLoc = ConsumeToken(); 741199990Srdivacky OwningExprResult AssignExpr(ParseAssignmentExpression()); 742199990Srdivacky if (!AssignExpr.isInvalid()) 743199990Srdivacky Actions.AddInitializerToDecl(DeclResult, move(AssignExpr)); 744199990Srdivacky } else { 745199990Srdivacky // FIXME: C++0x allows a braced-init-list 746199990Srdivacky Diag(Tok, diag::err_expected_equal_after_declarator); 747199990Srdivacky } 748199990Srdivacky 749199990Srdivacky return false; 750193326Sed} 751193326Sed 752193326Sed/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. 753193326Sed/// This should only be called when the current token is known to be part of 754193326Sed/// simple-type-specifier. 755193326Sed/// 756193326Sed/// simple-type-specifier: 757193326Sed/// '::'[opt] nested-name-specifier[opt] type-name 758193326Sed/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO] 759193326Sed/// char 760193326Sed/// wchar_t 761193326Sed/// bool 762193326Sed/// short 763193326Sed/// int 764193326Sed/// long 765193326Sed/// signed 766193326Sed/// unsigned 767193326Sed/// float 768193326Sed/// double 769193326Sed/// void 770193326Sed/// [GNU] typeof-specifier 771193326Sed/// [C++0x] auto [TODO] 772193326Sed/// 773193326Sed/// type-name: 774193326Sed/// class-name 775193326Sed/// enum-name 776193326Sed/// typedef-name 777193326Sed/// 778193326Sedvoid Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { 779193326Sed DS.SetRangeStart(Tok.getLocation()); 780193326Sed const char *PrevSpec; 781198092Srdivacky unsigned DiagID; 782193326Sed SourceLocation Loc = Tok.getLocation(); 783198092Srdivacky 784193326Sed switch (Tok.getKind()) { 785193326Sed case tok::identifier: // foo::bar 786193326Sed case tok::coloncolon: // ::foo::bar 787193326Sed assert(0 && "Annotation token should already be formed!"); 788198092Srdivacky default: 789193326Sed assert(0 && "Not a simple-type-specifier token!"); 790193326Sed abort(); 791193326Sed 792193326Sed // type-name 793193326Sed case tok::annot_typename: { 794198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, 795193326Sed Tok.getAnnotationValue()); 796193326Sed break; 797193326Sed } 798198092Srdivacky 799193326Sed // builtin types 800193326Sed case tok::kw_short: 801198092Srdivacky DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID); 802193326Sed break; 803193326Sed case tok::kw_long: 804198092Srdivacky DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID); 805193326Sed break; 806193326Sed case tok::kw_signed: 807198092Srdivacky DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID); 808193326Sed break; 809193326Sed case tok::kw_unsigned: 810198092Srdivacky DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, DiagID); 811193326Sed break; 812193326Sed case tok::kw_void: 813198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID); 814193326Sed break; 815193326Sed case tok::kw_char: 816198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID); 817193326Sed break; 818193326Sed case tok::kw_int: 819198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID); 820193326Sed break; 821193326Sed case tok::kw_float: 822198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID); 823193326Sed break; 824193326Sed case tok::kw_double: 825198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID); 826193326Sed break; 827193326Sed case tok::kw_wchar_t: 828198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID); 829193326Sed break; 830198092Srdivacky case tok::kw_char16_t: 831198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID); 832198092Srdivacky break; 833198092Srdivacky case tok::kw_char32_t: 834198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID); 835198092Srdivacky break; 836193326Sed case tok::kw_bool: 837198092Srdivacky DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID); 838193326Sed break; 839198092Srdivacky 840193326Sed // GNU typeof support. 841193326Sed case tok::kw_typeof: 842193326Sed ParseTypeofSpecifier(DS); 843193326Sed DS.Finish(Diags, PP); 844193326Sed return; 845193326Sed } 846193326Sed if (Tok.is(tok::annot_typename)) 847193326Sed DS.SetRangeEnd(Tok.getAnnotationEndLoc()); 848193326Sed else 849193326Sed DS.SetRangeEnd(Tok.getLocation()); 850193326Sed ConsumeToken(); 851193326Sed DS.Finish(Diags, PP); 852193326Sed} 853193326Sed 854193326Sed/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++ 855193326Sed/// [dcl.name]), which is a non-empty sequence of type-specifiers, 856193326Sed/// e.g., "const short int". Note that the DeclSpec is *not* finished 857193326Sed/// by parsing the type-specifier-seq, because these sequences are 858193326Sed/// typically followed by some form of declarator. Returns true and 859193326Sed/// emits diagnostics if this is not a type-specifier-seq, false 860193326Sed/// otherwise. 861193326Sed/// 862193326Sed/// type-specifier-seq: [C++ 8.1] 863193326Sed/// type-specifier type-specifier-seq[opt] 864193326Sed/// 865193326Sedbool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) { 866193326Sed DS.SetRangeStart(Tok.getLocation()); 867193326Sed const char *PrevSpec = 0; 868198092Srdivacky unsigned DiagID; 869198092Srdivacky bool isInvalid = 0; 870193326Sed 871193326Sed // Parse one or more of the type specifiers. 872203955Srdivacky if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, 873203955Srdivacky ParsedTemplateInfo(), /*SuppressDeclarations*/true)) { 874193326Sed Diag(Tok, diag::err_operator_missing_type_specifier); 875193326Sed return true; 876193326Sed } 877193326Sed 878203955Srdivacky while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID, 879203955Srdivacky ParsedTemplateInfo(), /*SuppressDeclarations*/true)) 880203955Srdivacky {} 881198092Srdivacky 882204643Srdivacky DS.Finish(Diags, PP); 883193326Sed return false; 884193326Sed} 885193326Sed 886198893Srdivacky/// \brief Finish parsing a C++ unqualified-id that is a template-id of 887198893Srdivacky/// some form. 888198893Srdivacky/// 889198893Srdivacky/// This routine is invoked when a '<' is encountered after an identifier or 890198893Srdivacky/// operator-function-id is parsed by \c ParseUnqualifiedId() to determine 891198893Srdivacky/// whether the unqualified-id is actually a template-id. This routine will 892198893Srdivacky/// then parse the template arguments and form the appropriate template-id to 893198893Srdivacky/// return to the caller. 894198893Srdivacky/// 895198893Srdivacky/// \param SS the nested-name-specifier that precedes this template-id, if 896198893Srdivacky/// we're actually parsing a qualified-id. 897198893Srdivacky/// 898198893Srdivacky/// \param Name for constructor and destructor names, this is the actual 899198893Srdivacky/// identifier that may be a template-name. 900198893Srdivacky/// 901198893Srdivacky/// \param NameLoc the location of the class-name in a constructor or 902198893Srdivacky/// destructor. 903198893Srdivacky/// 904198893Srdivacky/// \param EnteringContext whether we're entering the scope of the 905198893Srdivacky/// nested-name-specifier. 906198893Srdivacky/// 907198893Srdivacky/// \param ObjectType if this unqualified-id occurs within a member access 908198893Srdivacky/// expression, the type of the base object whose member is being accessed. 909198893Srdivacky/// 910198893Srdivacky/// \param Id as input, describes the template-name or operator-function-id 911198893Srdivacky/// that precedes the '<'. If template arguments were parsed successfully, 912198893Srdivacky/// will be updated with the template-id. 913198893Srdivacky/// 914204643Srdivacky/// \param AssumeTemplateId When true, this routine will assume that the name 915204643Srdivacky/// refers to a template without performing name lookup to verify. 916204643Srdivacky/// 917198893Srdivacky/// \returns true if a parse error occurred, false otherwise. 918198893Srdivackybool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, 919198893Srdivacky IdentifierInfo *Name, 920198893Srdivacky SourceLocation NameLoc, 921198893Srdivacky bool EnteringContext, 922198893Srdivacky TypeTy *ObjectType, 923204643Srdivacky UnqualifiedId &Id, 924204643Srdivacky bool AssumeTemplateId) { 925198893Srdivacky assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id"); 926198893Srdivacky 927198893Srdivacky TemplateTy Template; 928198893Srdivacky TemplateNameKind TNK = TNK_Non_template; 929198893Srdivacky switch (Id.getKind()) { 930198893Srdivacky case UnqualifiedId::IK_Identifier: 931198893Srdivacky case UnqualifiedId::IK_OperatorFunctionId: 932199990Srdivacky case UnqualifiedId::IK_LiteralOperatorId: 933204643Srdivacky if (AssumeTemplateId) { 934204643Srdivacky Template = Actions.ActOnDependentTemplateName(SourceLocation(), SS, 935204643Srdivacky Id, ObjectType, 936204643Srdivacky EnteringContext); 937204643Srdivacky TNK = TNK_Dependent_template_name; 938204643Srdivacky if (!Template.get()) 939204643Srdivacky return true; 940204643Srdivacky } else 941204643Srdivacky TNK = Actions.isTemplateName(CurScope, SS, Id, ObjectType, 942204643Srdivacky EnteringContext, Template); 943198893Srdivacky break; 944198893Srdivacky 945198893Srdivacky case UnqualifiedId::IK_ConstructorName: { 946198893Srdivacky UnqualifiedId TemplateName; 947198893Srdivacky TemplateName.setIdentifier(Name, NameLoc); 948198893Srdivacky TNK = Actions.isTemplateName(CurScope, SS, TemplateName, ObjectType, 949198893Srdivacky EnteringContext, Template); 950198893Srdivacky break; 951198893Srdivacky } 952198893Srdivacky 953198893Srdivacky case UnqualifiedId::IK_DestructorName: { 954198893Srdivacky UnqualifiedId TemplateName; 955198893Srdivacky TemplateName.setIdentifier(Name, NameLoc); 956198893Srdivacky if (ObjectType) { 957198893Srdivacky Template = Actions.ActOnDependentTemplateName(SourceLocation(), SS, 958199990Srdivacky TemplateName, ObjectType, 959199990Srdivacky EnteringContext); 960198893Srdivacky TNK = TNK_Dependent_template_name; 961198893Srdivacky if (!Template.get()) 962198893Srdivacky return true; 963198893Srdivacky } else { 964198893Srdivacky TNK = Actions.isTemplateName(CurScope, SS, TemplateName, ObjectType, 965198893Srdivacky EnteringContext, Template); 966198893Srdivacky 967198893Srdivacky if (TNK == TNK_Non_template && Id.DestructorName == 0) { 968204643Srdivacky Diag(NameLoc, diag::err_destructor_template_id) 969204643Srdivacky << Name << SS.getRange(); 970198893Srdivacky return true; 971198893Srdivacky } 972198893Srdivacky } 973198893Srdivacky break; 974198893Srdivacky } 975198893Srdivacky 976198893Srdivacky default: 977198893Srdivacky return false; 978198893Srdivacky } 979198893Srdivacky 980198893Srdivacky if (TNK == TNK_Non_template) 981198893Srdivacky return false; 982198893Srdivacky 983198893Srdivacky // Parse the enclosed template argument list. 984198893Srdivacky SourceLocation LAngleLoc, RAngleLoc; 985198893Srdivacky TemplateArgList TemplateArgs; 986198893Srdivacky if (ParseTemplateIdAfterTemplateName(Template, Id.StartLocation, 987198893Srdivacky &SS, true, LAngleLoc, 988198893Srdivacky TemplateArgs, 989198893Srdivacky RAngleLoc)) 990198893Srdivacky return true; 991198893Srdivacky 992198893Srdivacky if (Id.getKind() == UnqualifiedId::IK_Identifier || 993199990Srdivacky Id.getKind() == UnqualifiedId::IK_OperatorFunctionId || 994199990Srdivacky Id.getKind() == UnqualifiedId::IK_LiteralOperatorId) { 995198893Srdivacky // Form a parsed representation of the template-id to be stored in the 996198893Srdivacky // UnqualifiedId. 997198893Srdivacky TemplateIdAnnotation *TemplateId 998198893Srdivacky = TemplateIdAnnotation::Allocate(TemplateArgs.size()); 999198893Srdivacky 1000198893Srdivacky if (Id.getKind() == UnqualifiedId::IK_Identifier) { 1001198893Srdivacky TemplateId->Name = Id.Identifier; 1002198893Srdivacky TemplateId->Operator = OO_None; 1003198893Srdivacky TemplateId->TemplateNameLoc = Id.StartLocation; 1004198893Srdivacky } else { 1005198893Srdivacky TemplateId->Name = 0; 1006198893Srdivacky TemplateId->Operator = Id.OperatorFunctionId.Operator; 1007198893Srdivacky TemplateId->TemplateNameLoc = Id.StartLocation; 1008198893Srdivacky } 1009198893Srdivacky 1010198893Srdivacky TemplateId->Template = Template.getAs<void*>(); 1011198893Srdivacky TemplateId->Kind = TNK; 1012198893Srdivacky TemplateId->LAngleLoc = LAngleLoc; 1013198893Srdivacky TemplateId->RAngleLoc = RAngleLoc; 1014199482Srdivacky ParsedTemplateArgument *Args = TemplateId->getTemplateArgs(); 1015198893Srdivacky for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); 1016199482Srdivacky Arg != ArgEnd; ++Arg) 1017198893Srdivacky Args[Arg] = TemplateArgs[Arg]; 1018198893Srdivacky 1019198893Srdivacky Id.setTemplateId(TemplateId); 1020198893Srdivacky return false; 1021198893Srdivacky } 1022198893Srdivacky 1023198893Srdivacky // Bundle the template arguments together. 1024198893Srdivacky ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(), 1025198893Srdivacky TemplateArgs.size()); 1026198893Srdivacky 1027198893Srdivacky // Constructor and destructor names. 1028198893Srdivacky Action::TypeResult Type 1029198893Srdivacky = Actions.ActOnTemplateIdType(Template, NameLoc, 1030198893Srdivacky LAngleLoc, TemplateArgsPtr, 1031198893Srdivacky RAngleLoc); 1032198893Srdivacky if (Type.isInvalid()) 1033198893Srdivacky return true; 1034198893Srdivacky 1035198893Srdivacky if (Id.getKind() == UnqualifiedId::IK_ConstructorName) 1036198893Srdivacky Id.setConstructorName(Type.get(), NameLoc, RAngleLoc); 1037198893Srdivacky else 1038198893Srdivacky Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc); 1039198893Srdivacky 1040198893Srdivacky return false; 1041198893Srdivacky} 1042198893Srdivacky 1043198893Srdivacky/// \brief Parse an operator-function-id or conversion-function-id as part 1044198893Srdivacky/// of a C++ unqualified-id. 1045198893Srdivacky/// 1046198893Srdivacky/// This routine is responsible only for parsing the operator-function-id or 1047198893Srdivacky/// conversion-function-id; it does not handle template arguments in any way. 1048198893Srdivacky/// 1049198893Srdivacky/// \code 1050198893Srdivacky/// operator-function-id: [C++ 13.5] 1051198893Srdivacky/// 'operator' operator 1052198893Srdivacky/// 1053198893Srdivacky/// operator: one of 1054198893Srdivacky/// new delete new[] delete[] 1055198893Srdivacky/// + - * / % ^ & | ~ 1056198893Srdivacky/// ! = < > += -= *= /= %= 1057198893Srdivacky/// ^= &= |= << >> >>= <<= == != 1058198893Srdivacky/// <= >= && || ++ -- , ->* -> 1059198893Srdivacky/// () [] 1060198893Srdivacky/// 1061198893Srdivacky/// conversion-function-id: [C++ 12.3.2] 1062198893Srdivacky/// operator conversion-type-id 1063198893Srdivacky/// 1064198893Srdivacky/// conversion-type-id: 1065198893Srdivacky/// type-specifier-seq conversion-declarator[opt] 1066198893Srdivacky/// 1067198893Srdivacky/// conversion-declarator: 1068198893Srdivacky/// ptr-operator conversion-declarator[opt] 1069198893Srdivacky/// \endcode 1070198893Srdivacky/// 1071198893Srdivacky/// \param The nested-name-specifier that preceded this unqualified-id. If 1072198893Srdivacky/// non-empty, then we are parsing the unqualified-id of a qualified-id. 1073198893Srdivacky/// 1074198893Srdivacky/// \param EnteringContext whether we are entering the scope of the 1075198893Srdivacky/// nested-name-specifier. 1076198893Srdivacky/// 1077198893Srdivacky/// \param ObjectType if this unqualified-id occurs within a member access 1078198893Srdivacky/// expression, the type of the base object whose member is being accessed. 1079198893Srdivacky/// 1080198893Srdivacky/// \param Result on a successful parse, contains the parsed unqualified-id. 1081198893Srdivacky/// 1082198893Srdivacky/// \returns true if parsing fails, false otherwise. 1083198893Srdivackybool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, 1084198893Srdivacky TypeTy *ObjectType, 1085198893Srdivacky UnqualifiedId &Result) { 1086198893Srdivacky assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); 1087198893Srdivacky 1088198893Srdivacky // Consume the 'operator' keyword. 1089198893Srdivacky SourceLocation KeywordLoc = ConsumeToken(); 1090198893Srdivacky 1091198893Srdivacky // Determine what kind of operator name we have. 1092198893Srdivacky unsigned SymbolIdx = 0; 1093198893Srdivacky SourceLocation SymbolLocations[3]; 1094198893Srdivacky OverloadedOperatorKind Op = OO_None; 1095198893Srdivacky switch (Tok.getKind()) { 1096198893Srdivacky case tok::kw_new: 1097198893Srdivacky case tok::kw_delete: { 1098198893Srdivacky bool isNew = Tok.getKind() == tok::kw_new; 1099198893Srdivacky // Consume the 'new' or 'delete'. 1100198893Srdivacky SymbolLocations[SymbolIdx++] = ConsumeToken(); 1101198893Srdivacky if (Tok.is(tok::l_square)) { 1102198893Srdivacky // Consume the '['. 1103198893Srdivacky SourceLocation LBracketLoc = ConsumeBracket(); 1104198893Srdivacky // Consume the ']'. 1105198893Srdivacky SourceLocation RBracketLoc = MatchRHSPunctuation(tok::r_square, 1106198893Srdivacky LBracketLoc); 1107198893Srdivacky if (RBracketLoc.isInvalid()) 1108198893Srdivacky return true; 1109198893Srdivacky 1110198893Srdivacky SymbolLocations[SymbolIdx++] = LBracketLoc; 1111198893Srdivacky SymbolLocations[SymbolIdx++] = RBracketLoc; 1112198893Srdivacky Op = isNew? OO_Array_New : OO_Array_Delete; 1113198893Srdivacky } else { 1114198893Srdivacky Op = isNew? OO_New : OO_Delete; 1115198893Srdivacky } 1116198893Srdivacky break; 1117198893Srdivacky } 1118198893Srdivacky 1119198893Srdivacky#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 1120198893Srdivacky case tok::Token: \ 1121198893Srdivacky SymbolLocations[SymbolIdx++] = ConsumeToken(); \ 1122198893Srdivacky Op = OO_##Name; \ 1123198893Srdivacky break; 1124198893Srdivacky#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 1125198893Srdivacky#include "clang/Basic/OperatorKinds.def" 1126198893Srdivacky 1127198893Srdivacky case tok::l_paren: { 1128198893Srdivacky // Consume the '('. 1129198893Srdivacky SourceLocation LParenLoc = ConsumeParen(); 1130198893Srdivacky // Consume the ')'. 1131198893Srdivacky SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, 1132198893Srdivacky LParenLoc); 1133198893Srdivacky if (RParenLoc.isInvalid()) 1134198893Srdivacky return true; 1135198893Srdivacky 1136198893Srdivacky SymbolLocations[SymbolIdx++] = LParenLoc; 1137198893Srdivacky SymbolLocations[SymbolIdx++] = RParenLoc; 1138198893Srdivacky Op = OO_Call; 1139198893Srdivacky break; 1140198893Srdivacky } 1141198893Srdivacky 1142198893Srdivacky case tok::l_square: { 1143198893Srdivacky // Consume the '['. 1144198893Srdivacky SourceLocation LBracketLoc = ConsumeBracket(); 1145198893Srdivacky // Consume the ']'. 1146198893Srdivacky SourceLocation RBracketLoc = MatchRHSPunctuation(tok::r_square, 1147198893Srdivacky LBracketLoc); 1148198893Srdivacky if (RBracketLoc.isInvalid()) 1149198893Srdivacky return true; 1150198893Srdivacky 1151198893Srdivacky SymbolLocations[SymbolIdx++] = LBracketLoc; 1152198893Srdivacky SymbolLocations[SymbolIdx++] = RBracketLoc; 1153198893Srdivacky Op = OO_Subscript; 1154198893Srdivacky break; 1155198893Srdivacky } 1156198893Srdivacky 1157198893Srdivacky case tok::code_completion: { 1158198893Srdivacky // Code completion for the operator name. 1159198893Srdivacky Actions.CodeCompleteOperatorName(CurScope); 1160198893Srdivacky 1161198893Srdivacky // Consume the operator token. 1162198893Srdivacky ConsumeToken(); 1163198893Srdivacky 1164198893Srdivacky // Don't try to parse any further. 1165198893Srdivacky return true; 1166198893Srdivacky } 1167198893Srdivacky 1168198893Srdivacky default: 1169198893Srdivacky break; 1170198893Srdivacky } 1171198893Srdivacky 1172198893Srdivacky if (Op != OO_None) { 1173198893Srdivacky // We have parsed an operator-function-id. 1174198893Srdivacky Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations); 1175198893Srdivacky return false; 1176198893Srdivacky } 1177199990Srdivacky 1178199990Srdivacky // Parse a literal-operator-id. 1179199990Srdivacky // 1180199990Srdivacky // literal-operator-id: [C++0x 13.5.8] 1181199990Srdivacky // operator "" identifier 1182199990Srdivacky 1183199990Srdivacky if (getLang().CPlusPlus0x && Tok.is(tok::string_literal)) { 1184199990Srdivacky if (Tok.getLength() != 2) 1185199990Srdivacky Diag(Tok.getLocation(), diag::err_operator_string_not_empty); 1186199990Srdivacky ConsumeStringToken(); 1187199990Srdivacky 1188199990Srdivacky if (Tok.isNot(tok::identifier)) { 1189199990Srdivacky Diag(Tok.getLocation(), diag::err_expected_ident); 1190199990Srdivacky return true; 1191199990Srdivacky } 1192199990Srdivacky 1193199990Srdivacky IdentifierInfo *II = Tok.getIdentifierInfo(); 1194199990Srdivacky Result.setLiteralOperatorId(II, KeywordLoc, ConsumeToken()); 1195199990Srdivacky return false; 1196199990Srdivacky } 1197198893Srdivacky 1198198893Srdivacky // Parse a conversion-function-id. 1199198893Srdivacky // 1200198893Srdivacky // conversion-function-id: [C++ 12.3.2] 1201198893Srdivacky // operator conversion-type-id 1202198893Srdivacky // 1203198893Srdivacky // conversion-type-id: 1204198893Srdivacky // type-specifier-seq conversion-declarator[opt] 1205198893Srdivacky // 1206198893Srdivacky // conversion-declarator: 1207198893Srdivacky // ptr-operator conversion-declarator[opt] 1208198893Srdivacky 1209198893Srdivacky // Parse the type-specifier-seq. 1210198893Srdivacky DeclSpec DS; 1211199990Srdivacky if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType? 1212198893Srdivacky return true; 1213198893Srdivacky 1214198893Srdivacky // Parse the conversion-declarator, which is merely a sequence of 1215198893Srdivacky // ptr-operators. 1216198893Srdivacky Declarator D(DS, Declarator::TypeNameContext); 1217198893Srdivacky ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); 1218198893Srdivacky 1219198893Srdivacky // Finish up the type. 1220198893Srdivacky Action::TypeResult Ty = Actions.ActOnTypeName(CurScope, D); 1221198893Srdivacky if (Ty.isInvalid()) 1222198893Srdivacky return true; 1223198893Srdivacky 1224198893Srdivacky // Note that this is a conversion-function-id. 1225198893Srdivacky Result.setConversionFunctionId(KeywordLoc, Ty.get(), 1226198893Srdivacky D.getSourceRange().getEnd()); 1227198893Srdivacky return false; 1228198893Srdivacky} 1229198893Srdivacky 1230198893Srdivacky/// \brief Parse a C++ unqualified-id (or a C identifier), which describes the 1231198893Srdivacky/// name of an entity. 1232198893Srdivacky/// 1233198893Srdivacky/// \code 1234198893Srdivacky/// unqualified-id: [C++ expr.prim.general] 1235198893Srdivacky/// identifier 1236198893Srdivacky/// operator-function-id 1237198893Srdivacky/// conversion-function-id 1238198893Srdivacky/// [C++0x] literal-operator-id [TODO] 1239198893Srdivacky/// ~ class-name 1240198893Srdivacky/// template-id 1241198893Srdivacky/// 1242198893Srdivacky/// \endcode 1243198893Srdivacky/// 1244198893Srdivacky/// \param The nested-name-specifier that preceded this unqualified-id. If 1245198893Srdivacky/// non-empty, then we are parsing the unqualified-id of a qualified-id. 1246198893Srdivacky/// 1247198893Srdivacky/// \param EnteringContext whether we are entering the scope of the 1248198893Srdivacky/// nested-name-specifier. 1249198893Srdivacky/// 1250198893Srdivacky/// \param AllowDestructorName whether we allow parsing of a destructor name. 1251198893Srdivacky/// 1252198893Srdivacky/// \param AllowConstructorName whether we allow parsing a constructor name. 1253198893Srdivacky/// 1254198893Srdivacky/// \param ObjectType if this unqualified-id occurs within a member access 1255198893Srdivacky/// expression, the type of the base object whose member is being accessed. 1256198893Srdivacky/// 1257198893Srdivacky/// \param Result on a successful parse, contains the parsed unqualified-id. 1258198893Srdivacky/// 1259198893Srdivacky/// \returns true if parsing fails, false otherwise. 1260198893Srdivackybool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, 1261198893Srdivacky bool AllowDestructorName, 1262198893Srdivacky bool AllowConstructorName, 1263198893Srdivacky TypeTy *ObjectType, 1264198893Srdivacky UnqualifiedId &Result) { 1265198893Srdivacky // unqualified-id: 1266198893Srdivacky // identifier 1267198893Srdivacky // template-id (when it hasn't already been annotated) 1268198893Srdivacky if (Tok.is(tok::identifier)) { 1269198893Srdivacky // Consume the identifier. 1270198893Srdivacky IdentifierInfo *Id = Tok.getIdentifierInfo(); 1271198893Srdivacky SourceLocation IdLoc = ConsumeToken(); 1272198893Srdivacky 1273202379Srdivacky if (!getLang().CPlusPlus) { 1274202379Srdivacky // If we're not in C++, only identifiers matter. Record the 1275202379Srdivacky // identifier and return. 1276202379Srdivacky Result.setIdentifier(Id, IdLoc); 1277202379Srdivacky return false; 1278202379Srdivacky } 1279202379Srdivacky 1280198893Srdivacky if (AllowConstructorName && 1281198893Srdivacky Actions.isCurrentClassName(*Id, CurScope, &SS)) { 1282198893Srdivacky // We have parsed a constructor name. 1283198893Srdivacky Result.setConstructorName(Actions.getTypeName(*Id, IdLoc, CurScope, 1284198893Srdivacky &SS, false), 1285198893Srdivacky IdLoc, IdLoc); 1286198893Srdivacky } else { 1287198893Srdivacky // We have parsed an identifier. 1288198893Srdivacky Result.setIdentifier(Id, IdLoc); 1289198893Srdivacky } 1290198893Srdivacky 1291198893Srdivacky // If the next token is a '<', we may have a template. 1292198893Srdivacky if (Tok.is(tok::less)) 1293198893Srdivacky return ParseUnqualifiedIdTemplateId(SS, Id, IdLoc, EnteringContext, 1294198893Srdivacky ObjectType, Result); 1295198893Srdivacky 1296198893Srdivacky return false; 1297198893Srdivacky } 1298198893Srdivacky 1299198893Srdivacky // unqualified-id: 1300198893Srdivacky // template-id (already parsed and annotated) 1301198893Srdivacky if (Tok.is(tok::annot_template_id)) { 1302202379Srdivacky TemplateIdAnnotation *TemplateId 1303202379Srdivacky = static_cast<TemplateIdAnnotation*>(Tok.getAnnotationValue()); 1304202379Srdivacky 1305202379Srdivacky // If the template-name names the current class, then this is a constructor 1306202379Srdivacky if (AllowConstructorName && TemplateId->Name && 1307202379Srdivacky Actions.isCurrentClassName(*TemplateId->Name, CurScope, &SS)) { 1308202379Srdivacky if (SS.isSet()) { 1309202379Srdivacky // C++ [class.qual]p2 specifies that a qualified template-name 1310202379Srdivacky // is taken as the constructor name where a constructor can be 1311202379Srdivacky // declared. Thus, the template arguments are extraneous, so 1312202379Srdivacky // complain about them and remove them entirely. 1313202379Srdivacky Diag(TemplateId->TemplateNameLoc, 1314202379Srdivacky diag::err_out_of_line_constructor_template_id) 1315202379Srdivacky << TemplateId->Name 1316202379Srdivacky << CodeModificationHint::CreateRemoval( 1317202379Srdivacky SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)); 1318202379Srdivacky Result.setConstructorName(Actions.getTypeName(*TemplateId->Name, 1319202379Srdivacky TemplateId->TemplateNameLoc, 1320202379Srdivacky CurScope, 1321202379Srdivacky &SS, false), 1322202379Srdivacky TemplateId->TemplateNameLoc, 1323202379Srdivacky TemplateId->RAngleLoc); 1324202379Srdivacky TemplateId->Destroy(); 1325202379Srdivacky ConsumeToken(); 1326202379Srdivacky return false; 1327202379Srdivacky } 1328202379Srdivacky 1329202379Srdivacky Result.setConstructorTemplateId(TemplateId); 1330202379Srdivacky ConsumeToken(); 1331202379Srdivacky return false; 1332202379Srdivacky } 1333202379Srdivacky 1334198893Srdivacky // We have already parsed a template-id; consume the annotation token as 1335198893Srdivacky // our unqualified-id. 1336202379Srdivacky Result.setTemplateId(TemplateId); 1337198893Srdivacky ConsumeToken(); 1338198893Srdivacky return false; 1339198893Srdivacky } 1340198893Srdivacky 1341198893Srdivacky // unqualified-id: 1342198893Srdivacky // operator-function-id 1343198893Srdivacky // conversion-function-id 1344198893Srdivacky if (Tok.is(tok::kw_operator)) { 1345198893Srdivacky if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result)) 1346198893Srdivacky return true; 1347198893Srdivacky 1348199990Srdivacky // If we have an operator-function-id or a literal-operator-id and the next 1349199990Srdivacky // token is a '<', we may have a 1350198893Srdivacky // 1351198893Srdivacky // template-id: 1352198893Srdivacky // operator-function-id < template-argument-list[opt] > 1353199990Srdivacky if ((Result.getKind() == UnqualifiedId::IK_OperatorFunctionId || 1354199990Srdivacky Result.getKind() == UnqualifiedId::IK_LiteralOperatorId) && 1355198893Srdivacky Tok.is(tok::less)) 1356198893Srdivacky return ParseUnqualifiedIdTemplateId(SS, 0, SourceLocation(), 1357198893Srdivacky EnteringContext, ObjectType, 1358198893Srdivacky Result); 1359198893Srdivacky 1360198893Srdivacky return false; 1361198893Srdivacky } 1362198893Srdivacky 1363202379Srdivacky if (getLang().CPlusPlus && 1364202379Srdivacky (AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) { 1365198893Srdivacky // C++ [expr.unary.op]p10: 1366198893Srdivacky // There is an ambiguity in the unary-expression ~X(), where X is a 1367198893Srdivacky // class-name. The ambiguity is resolved in favor of treating ~ as a 1368198893Srdivacky // unary complement rather than treating ~X as referring to a destructor. 1369198893Srdivacky 1370198893Srdivacky // Parse the '~'. 1371198893Srdivacky SourceLocation TildeLoc = ConsumeToken(); 1372198893Srdivacky 1373198893Srdivacky // Parse the class-name. 1374198893Srdivacky if (Tok.isNot(tok::identifier)) { 1375204643Srdivacky Diag(Tok, diag::err_destructor_tilde_identifier); 1376198893Srdivacky return true; 1377198893Srdivacky } 1378198893Srdivacky 1379198893Srdivacky // Parse the class-name (or template-name in a simple-template-id). 1380198893Srdivacky IdentifierInfo *ClassName = Tok.getIdentifierInfo(); 1381198893Srdivacky SourceLocation ClassNameLoc = ConsumeToken(); 1382198893Srdivacky 1383198893Srdivacky if (Tok.is(tok::less)) { 1384198893Srdivacky Result.setDestructorName(TildeLoc, 0, ClassNameLoc); 1385198893Srdivacky return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc, 1386198893Srdivacky EnteringContext, ObjectType, Result); 1387198893Srdivacky } 1388198893Srdivacky 1389198893Srdivacky // Note that this is a destructor name. 1390204643Srdivacky Action::TypeTy *Ty = Actions.getDestructorName(TildeLoc, *ClassName, 1391204643Srdivacky ClassNameLoc, CurScope, 1392204643Srdivacky SS, ObjectType, 1393204643Srdivacky EnteringContext); 1394204643Srdivacky if (!Ty) 1395198893Srdivacky return true; 1396204643Srdivacky 1397198893Srdivacky Result.setDestructorName(TildeLoc, Ty, ClassNameLoc); 1398198893Srdivacky return false; 1399198893Srdivacky } 1400198893Srdivacky 1401198893Srdivacky Diag(Tok, diag::err_expected_unqualified_id) 1402198893Srdivacky << getLang().CPlusPlus; 1403198893Srdivacky return true; 1404198893Srdivacky} 1405198893Srdivacky 1406193326Sed/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate 1407193326Sed/// memory in a typesafe manner and call constructors. 1408198092Srdivacky/// 1409193326Sed/// This method is called to parse the new expression after the optional :: has 1410193326Sed/// been already parsed. If the :: was present, "UseGlobal" is true and "Start" 1411193326Sed/// is its location. Otherwise, "Start" is the location of the 'new' token. 1412193326Sed/// 1413193326Sed/// new-expression: 1414193326Sed/// '::'[opt] 'new' new-placement[opt] new-type-id 1415193326Sed/// new-initializer[opt] 1416193326Sed/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 1417193326Sed/// new-initializer[opt] 1418193326Sed/// 1419193326Sed/// new-placement: 1420193326Sed/// '(' expression-list ')' 1421193326Sed/// 1422193326Sed/// new-type-id: 1423193326Sed/// type-specifier-seq new-declarator[opt] 1424193326Sed/// 1425193326Sed/// new-declarator: 1426193326Sed/// ptr-operator new-declarator[opt] 1427193326Sed/// direct-new-declarator 1428193326Sed/// 1429193326Sed/// new-initializer: 1430193326Sed/// '(' expression-list[opt] ')' 1431193326Sed/// [C++0x] braced-init-list [TODO] 1432193326Sed/// 1433193326SedParser::OwningExprResult 1434193326SedParser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { 1435193326Sed assert(Tok.is(tok::kw_new) && "expected 'new' token"); 1436193326Sed ConsumeToken(); // Consume 'new' 1437193326Sed 1438193326Sed // A '(' now can be a new-placement or the '(' wrapping the type-id in the 1439193326Sed // second form of new-expression. It can't be a new-type-id. 1440193326Sed 1441193326Sed ExprVector PlacementArgs(Actions); 1442193326Sed SourceLocation PlacementLParen, PlacementRParen; 1443193326Sed 1444193326Sed bool ParenTypeId; 1445193326Sed DeclSpec DS; 1446193326Sed Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); 1447193326Sed if (Tok.is(tok::l_paren)) { 1448193326Sed // If it turns out to be a placement, we change the type location. 1449193326Sed PlacementLParen = ConsumeParen(); 1450193326Sed if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) { 1451193326Sed SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 1452193326Sed return ExprError(); 1453193326Sed } 1454193326Sed 1455193326Sed PlacementRParen = MatchRHSPunctuation(tok::r_paren, PlacementLParen); 1456193326Sed if (PlacementRParen.isInvalid()) { 1457193326Sed SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 1458193326Sed return ExprError(); 1459193326Sed } 1460193326Sed 1461193326Sed if (PlacementArgs.empty()) { 1462193326Sed // Reset the placement locations. There was no placement. 1463193326Sed PlacementLParen = PlacementRParen = SourceLocation(); 1464193326Sed ParenTypeId = true; 1465193326Sed } else { 1466193326Sed // We still need the type. 1467193326Sed if (Tok.is(tok::l_paren)) { 1468193326Sed SourceLocation LParen = ConsumeParen(); 1469193326Sed ParseSpecifierQualifierList(DS); 1470193326Sed DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 1471193326Sed ParseDeclarator(DeclaratorInfo); 1472193326Sed MatchRHSPunctuation(tok::r_paren, LParen); 1473193326Sed ParenTypeId = true; 1474193326Sed } else { 1475193326Sed if (ParseCXXTypeSpecifierSeq(DS)) 1476193326Sed DeclaratorInfo.setInvalidType(true); 1477193326Sed else { 1478193326Sed DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 1479193326Sed ParseDeclaratorInternal(DeclaratorInfo, 1480193326Sed &Parser::ParseDirectNewDeclarator); 1481193326Sed } 1482193326Sed ParenTypeId = false; 1483193326Sed } 1484193326Sed } 1485193326Sed } else { 1486193326Sed // A new-type-id is a simplified type-id, where essentially the 1487193326Sed // direct-declarator is replaced by a direct-new-declarator. 1488193326Sed if (ParseCXXTypeSpecifierSeq(DS)) 1489193326Sed DeclaratorInfo.setInvalidType(true); 1490193326Sed else { 1491193326Sed DeclaratorInfo.SetSourceRange(DS.getSourceRange()); 1492193326Sed ParseDeclaratorInternal(DeclaratorInfo, 1493193326Sed &Parser::ParseDirectNewDeclarator); 1494193326Sed } 1495193326Sed ParenTypeId = false; 1496193326Sed } 1497193326Sed if (DeclaratorInfo.isInvalidType()) { 1498193326Sed SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 1499193326Sed return ExprError(); 1500193326Sed } 1501193326Sed 1502193326Sed ExprVector ConstructorArgs(Actions); 1503193326Sed SourceLocation ConstructorLParen, ConstructorRParen; 1504193326Sed 1505193326Sed if (Tok.is(tok::l_paren)) { 1506193326Sed ConstructorLParen = ConsumeParen(); 1507193326Sed if (Tok.isNot(tok::r_paren)) { 1508193326Sed CommaLocsTy CommaLocs; 1509193326Sed if (ParseExpressionList(ConstructorArgs, CommaLocs)) { 1510193326Sed SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 1511193326Sed return ExprError(); 1512193326Sed } 1513193326Sed } 1514193326Sed ConstructorRParen = MatchRHSPunctuation(tok::r_paren, ConstructorLParen); 1515193326Sed if (ConstructorRParen.isInvalid()) { 1516193326Sed SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true); 1517193326Sed return ExprError(); 1518193326Sed } 1519193326Sed } 1520193326Sed 1521193326Sed return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen, 1522193326Sed move_arg(PlacementArgs), PlacementRParen, 1523193326Sed ParenTypeId, DeclaratorInfo, ConstructorLParen, 1524193326Sed move_arg(ConstructorArgs), ConstructorRParen); 1525193326Sed} 1526193326Sed 1527193326Sed/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be 1528193326Sed/// passed to ParseDeclaratorInternal. 1529193326Sed/// 1530193326Sed/// direct-new-declarator: 1531193326Sed/// '[' expression ']' 1532193326Sed/// direct-new-declarator '[' constant-expression ']' 1533193326Sed/// 1534193326Sedvoid Parser::ParseDirectNewDeclarator(Declarator &D) { 1535193326Sed // Parse the array dimensions. 1536193326Sed bool first = true; 1537193326Sed while (Tok.is(tok::l_square)) { 1538193326Sed SourceLocation LLoc = ConsumeBracket(); 1539193326Sed OwningExprResult Size(first ? ParseExpression() 1540193326Sed : ParseConstantExpression()); 1541193326Sed if (Size.isInvalid()) { 1542193326Sed // Recover 1543193326Sed SkipUntil(tok::r_square); 1544193326Sed return; 1545193326Sed } 1546193326Sed first = false; 1547193326Sed 1548193326Sed SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc); 1549193326Sed D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false, 1550198092Srdivacky Size.release(), LLoc, RLoc), 1551193326Sed RLoc); 1552193326Sed 1553193326Sed if (RLoc.isInvalid()) 1554193326Sed return; 1555193326Sed } 1556193326Sed} 1557193326Sed 1558193326Sed/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id. 1559193326Sed/// This ambiguity appears in the syntax of the C++ new operator. 1560193326Sed/// 1561193326Sed/// new-expression: 1562193326Sed/// '::'[opt] 'new' new-placement[opt] '(' type-id ')' 1563193326Sed/// new-initializer[opt] 1564193326Sed/// 1565193326Sed/// new-placement: 1566193326Sed/// '(' expression-list ')' 1567193326Sed/// 1568193326Sedbool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs, 1569193326Sed Declarator &D) { 1570193326Sed // The '(' was already consumed. 1571193326Sed if (isTypeIdInParens()) { 1572193326Sed ParseSpecifierQualifierList(D.getMutableDeclSpec()); 1573193326Sed D.SetSourceRange(D.getDeclSpec().getSourceRange()); 1574193326Sed ParseDeclarator(D); 1575193326Sed return D.isInvalidType(); 1576193326Sed } 1577193326Sed 1578193326Sed // It's not a type, it has to be an expression list. 1579193326Sed // Discard the comma locations - ActOnCXXNew has enough parameters. 1580193326Sed CommaLocsTy CommaLocs; 1581193326Sed return ParseExpressionList(PlacementArgs, CommaLocs); 1582193326Sed} 1583193326Sed 1584193326Sed/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used 1585193326Sed/// to free memory allocated by new. 1586193326Sed/// 1587193326Sed/// This method is called to parse the 'delete' expression after the optional 1588193326Sed/// '::' has been already parsed. If the '::' was present, "UseGlobal" is true 1589193326Sed/// and "Start" is its location. Otherwise, "Start" is the location of the 1590193326Sed/// 'delete' token. 1591193326Sed/// 1592193326Sed/// delete-expression: 1593193326Sed/// '::'[opt] 'delete' cast-expression 1594193326Sed/// '::'[opt] 'delete' '[' ']' cast-expression 1595193326SedParser::OwningExprResult 1596193326SedParser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { 1597193326Sed assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword"); 1598193326Sed ConsumeToken(); // Consume 'delete' 1599193326Sed 1600193326Sed // Array delete? 1601193326Sed bool ArrayDelete = false; 1602193326Sed if (Tok.is(tok::l_square)) { 1603193326Sed ArrayDelete = true; 1604193326Sed SourceLocation LHS = ConsumeBracket(); 1605193326Sed SourceLocation RHS = MatchRHSPunctuation(tok::r_square, LHS); 1606193326Sed if (RHS.isInvalid()) 1607193326Sed return ExprError(); 1608193326Sed } 1609193326Sed 1610193326Sed OwningExprResult Operand(ParseCastExpression(false)); 1611193326Sed if (Operand.isInvalid()) 1612193326Sed return move(Operand); 1613193326Sed 1614193326Sed return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand)); 1615193326Sed} 1616193326Sed 1617198092Srdivackystatic UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) { 1618193326Sed switch(kind) { 1619193326Sed default: assert(false && "Not a known unary type trait."); 1620193326Sed case tok::kw___has_nothrow_assign: return UTT_HasNothrowAssign; 1621193326Sed case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy; 1622193326Sed case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor; 1623193326Sed case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign; 1624193326Sed case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy; 1625193326Sed case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor; 1626193326Sed case tok::kw___has_trivial_destructor: return UTT_HasTrivialDestructor; 1627193326Sed case tok::kw___has_virtual_destructor: return UTT_HasVirtualDestructor; 1628193326Sed case tok::kw___is_abstract: return UTT_IsAbstract; 1629193326Sed case tok::kw___is_class: return UTT_IsClass; 1630193326Sed case tok::kw___is_empty: return UTT_IsEmpty; 1631193326Sed case tok::kw___is_enum: return UTT_IsEnum; 1632193326Sed case tok::kw___is_pod: return UTT_IsPOD; 1633193326Sed case tok::kw___is_polymorphic: return UTT_IsPolymorphic; 1634193326Sed case tok::kw___is_union: return UTT_IsUnion; 1635200583Srdivacky case tok::kw___is_literal: return UTT_IsLiteral; 1636193326Sed } 1637193326Sed} 1638193326Sed 1639193326Sed/// ParseUnaryTypeTrait - Parse the built-in unary type-trait 1640193326Sed/// pseudo-functions that allow implementation of the TR1/C++0x type traits 1641193326Sed/// templates. 1642193326Sed/// 1643193326Sed/// primary-expression: 1644193326Sed/// [GNU] unary-type-trait '(' type-id ')' 1645193326Sed/// 1646198092SrdivackyParser::OwningExprResult Parser::ParseUnaryTypeTrait() { 1647193326Sed UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind()); 1648193326Sed SourceLocation Loc = ConsumeToken(); 1649193326Sed 1650193326Sed SourceLocation LParen = Tok.getLocation(); 1651193326Sed if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen)) 1652193326Sed return ExprError(); 1653193326Sed 1654193326Sed // FIXME: Error reporting absolutely sucks! If the this fails to parse a type 1655193326Sed // there will be cryptic errors about mismatched parentheses and missing 1656193326Sed // specifiers. 1657193326Sed TypeResult Ty = ParseTypeName(); 1658193326Sed 1659193326Sed SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen); 1660193326Sed 1661193326Sed if (Ty.isInvalid()) 1662193326Sed return ExprError(); 1663193326Sed 1664193326Sed return Actions.ActOnUnaryTypeTrait(UTT, Loc, LParen, Ty.get(), RParen); 1665193326Sed} 1666193326Sed 1667193326Sed/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a 1668193326Sed/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate 1669193326Sed/// based on the context past the parens. 1670193326SedParser::OwningExprResult 1671193326SedParser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, 1672193326Sed TypeTy *&CastTy, 1673193326Sed SourceLocation LParenLoc, 1674193326Sed SourceLocation &RParenLoc) { 1675193326Sed assert(getLang().CPlusPlus && "Should only be called for C++!"); 1676193326Sed assert(ExprType == CastExpr && "Compound literals are not ambiguous!"); 1677193326Sed assert(isTypeIdInParens() && "Not a type-id!"); 1678193326Sed 1679193326Sed OwningExprResult Result(Actions, true); 1680193326Sed CastTy = 0; 1681193326Sed 1682193326Sed // We need to disambiguate a very ugly part of the C++ syntax: 1683193326Sed // 1684193326Sed // (T())x; - type-id 1685193326Sed // (T())*x; - type-id 1686193326Sed // (T())/x; - expression 1687193326Sed // (T()); - expression 1688193326Sed // 1689193326Sed // The bad news is that we cannot use the specialized tentative parser, since 1690193326Sed // it can only verify that the thing inside the parens can be parsed as 1691193326Sed // type-id, it is not useful for determining the context past the parens. 1692193326Sed // 1693193326Sed // The good news is that the parser can disambiguate this part without 1694193326Sed // making any unnecessary Action calls. 1695193326Sed // 1696193326Sed // It uses a scheme similar to parsing inline methods. The parenthesized 1697193326Sed // tokens are cached, the context that follows is determined (possibly by 1698193326Sed // parsing a cast-expression), and then we re-introduce the cached tokens 1699193326Sed // into the token stream and parse them appropriately. 1700193326Sed 1701198092Srdivacky ParenParseOption ParseAs; 1702193326Sed CachedTokens Toks; 1703193326Sed 1704193326Sed // Store the tokens of the parentheses. We will parse them after we determine 1705193326Sed // the context that follows them. 1706193326Sed if (!ConsumeAndStoreUntil(tok::r_paren, tok::unknown, Toks, tok::semi)) { 1707193326Sed // We didn't find the ')' we expected. 1708193326Sed MatchRHSPunctuation(tok::r_paren, LParenLoc); 1709193326Sed return ExprError(); 1710193326Sed } 1711193326Sed 1712193326Sed if (Tok.is(tok::l_brace)) { 1713193326Sed ParseAs = CompoundLiteral; 1714193326Sed } else { 1715193326Sed bool NotCastExpr; 1716193326Sed // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression 1717193326Sed if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) { 1718193326Sed NotCastExpr = true; 1719193326Sed } else { 1720193326Sed // Try parsing the cast-expression that may follow. 1721193326Sed // If it is not a cast-expression, NotCastExpr will be true and no token 1722193326Sed // will be consumed. 1723193326Sed Result = ParseCastExpression(false/*isUnaryExpression*/, 1724193326Sed false/*isAddressofOperand*/, 1725198092Srdivacky NotCastExpr, false); 1726193326Sed } 1727193326Sed 1728193326Sed // If we parsed a cast-expression, it's really a type-id, otherwise it's 1729193326Sed // an expression. 1730193326Sed ParseAs = NotCastExpr ? SimpleExpr : CastExpr; 1731193326Sed } 1732193326Sed 1733198092Srdivacky // The current token should go after the cached tokens. 1734193326Sed Toks.push_back(Tok); 1735193326Sed // Re-enter the stored parenthesized tokens into the token stream, so we may 1736193326Sed // parse them now. 1737193326Sed PP.EnterTokenStream(Toks.data(), Toks.size(), 1738193326Sed true/*DisableMacroExpansion*/, false/*OwnsTokens*/); 1739193326Sed // Drop the current token and bring the first cached one. It's the same token 1740193326Sed // as when we entered this function. 1741193326Sed ConsumeAnyToken(); 1742193326Sed 1743193326Sed if (ParseAs >= CompoundLiteral) { 1744193326Sed TypeResult Ty = ParseTypeName(); 1745193326Sed 1746193326Sed // Match the ')'. 1747193326Sed if (Tok.is(tok::r_paren)) 1748193326Sed RParenLoc = ConsumeParen(); 1749193326Sed else 1750193326Sed MatchRHSPunctuation(tok::r_paren, LParenLoc); 1751193326Sed 1752193326Sed if (ParseAs == CompoundLiteral) { 1753193326Sed ExprType = CompoundLiteral; 1754193326Sed return ParseCompoundLiteralExpression(Ty.get(), LParenLoc, RParenLoc); 1755193326Sed } 1756198092Srdivacky 1757193326Sed // We parsed '(' type-id ')' and the thing after it wasn't a '{'. 1758193326Sed assert(ParseAs == CastExpr); 1759193326Sed 1760193326Sed if (Ty.isInvalid()) 1761193326Sed return ExprError(); 1762193326Sed 1763193326Sed CastTy = Ty.get(); 1764193326Sed 1765193326Sed // Result is what ParseCastExpression returned earlier. 1766193326Sed if (!Result.isInvalid()) 1767198092Srdivacky Result = Actions.ActOnCastExpr(CurScope, LParenLoc, CastTy, RParenLoc, 1768198092Srdivacky move(Result)); 1769193326Sed return move(Result); 1770193326Sed } 1771198092Srdivacky 1772193326Sed // Not a compound literal, and not followed by a cast-expression. 1773193326Sed assert(ParseAs == SimpleExpr); 1774193326Sed 1775193326Sed ExprType = SimpleExpr; 1776193326Sed Result = ParseExpression(); 1777193326Sed if (!Result.isInvalid() && Tok.is(tok::r_paren)) 1778193326Sed Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), move(Result)); 1779193326Sed 1780193326Sed // Match the ')'. 1781193326Sed if (Result.isInvalid()) { 1782193326Sed SkipUntil(tok::r_paren); 1783193326Sed return ExprError(); 1784193326Sed } 1785198092Srdivacky 1786193326Sed if (Tok.is(tok::r_paren)) 1787193326Sed RParenLoc = ConsumeParen(); 1788193326Sed else 1789193326Sed MatchRHSPunctuation(tok::r_paren, LParenLoc); 1790193326Sed 1791193326Sed return move(Result); 1792193326Sed} 1793