ParseTemplate.cpp revision aaba5e346dffdbad5d1c42765a89e4a7afb0da67
1//===--- ParseTemplate.cpp - Template Parsing -----------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements parsing of C++ templates. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/Parse/Parser.h" 15#include "clang/Parse/ParseDiagnostic.h" 16#include "clang/Parse/DeclSpec.h" 17#include "clang/Parse/Scope.h" 18 19using namespace clang; 20 21/// ParseTemplateDeclaration - Parse a template declaration, which includes 22/// the template parameter list and either a function of class declaration. 23/// 24/// template-declaration: [C++ temp] 25/// 'export'[opt] 'template' '<' template-parameter-list '>' declaration 26Parser::DeclTy *Parser::ParseTemplateDeclaration(unsigned Context) { 27 assert((Tok.is(tok::kw_export) || Tok.is(tok::kw_template)) && 28 "Token does not start a template declaration."); 29 30 // Enter template-parameter scope. 31 ParseScope TemplateParmScope(this, Scope::TemplateParamScope); 32 33 // Parse multiple levels of template headers within this template 34 // parameter scope, e.g., 35 // 36 // template<typename T> 37 // template<typename U> 38 // class A<T>::B { ... }; 39 // 40 // We parse multiple levels non-recursively so that we can build a 41 // single data structure containing all of the template parameter 42 // lists easily differentiate between the case above and: 43 // 44 // template<typename T> 45 // class A { 46 // template<typename U> class B; 47 // }; 48 // 49 // In the first case, the action for declaring A<T>::B receives 50 // both template parameter lists. In the second case, the action for 51 // defining A<T>::B receives just the inner template parameter list 52 // (and retrieves the outer template parameter list from its 53 // context). 54 TemplateParameterLists ParamLists; 55 do { 56 // Consume the 'export', if any. 57 SourceLocation ExportLoc; 58 if (Tok.is(tok::kw_export)) { 59 ExportLoc = ConsumeToken(); 60 } 61 62 // Consume the 'template', which should be here. 63 SourceLocation TemplateLoc; 64 if (Tok.is(tok::kw_template)) { 65 TemplateLoc = ConsumeToken(); 66 } else { 67 Diag(Tok.getLocation(), diag::err_expected_template); 68 return 0; 69 } 70 71 // Parse the '<' template-parameter-list '>' 72 SourceLocation LAngleLoc, RAngleLoc; 73 TemplateParameterList TemplateParams; 74 ParseTemplateParameters(ParamLists.size(), TemplateParams, LAngleLoc, 75 RAngleLoc); 76 77 ParamLists.push_back( 78 Actions.ActOnTemplateParameterList(ParamLists.size(), ExportLoc, 79 TemplateLoc, LAngleLoc, 80 &TemplateParams[0], 81 TemplateParams.size(), RAngleLoc)); 82 } while (Tok.is(tok::kw_export) || Tok.is(tok::kw_template)); 83 84 // Parse the actual template declaration. 85 return ParseDeclarationOrFunctionDefinition(&ParamLists); 86} 87 88/// ParseTemplateParameters - Parses a template-parameter-list enclosed in 89/// angle brackets. Depth is the depth of this template-parameter-list, which 90/// is the number of template headers directly enclosing this template header. 91/// TemplateParams is the current list of template parameters we're building. 92/// The template parameter we parse will be added to this list. LAngleLoc and 93/// RAngleLoc will receive the positions of the '<' and '>', respectively, 94/// that enclose this template parameter list. 95bool Parser::ParseTemplateParameters(unsigned Depth, 96 TemplateParameterList &TemplateParams, 97 SourceLocation &LAngleLoc, 98 SourceLocation &RAngleLoc) { 99 // Get the template parameter list. 100 if(!Tok.is(tok::less)) { 101 Diag(Tok.getLocation(), diag::err_expected_less_after) << "template"; 102 return false; 103 } 104 LAngleLoc = ConsumeToken(); 105 106 // Try to parse the template parameter list. 107 if (Tok.is(tok::greater)) 108 RAngleLoc = ConsumeToken(); 109 else if(ParseTemplateParameterList(Depth, TemplateParams)) { 110 if(!Tok.is(tok::greater)) { 111 Diag(Tok.getLocation(), diag::err_expected_greater); 112 return false; 113 } 114 RAngleLoc = ConsumeToken(); 115 } 116 return true; 117} 118 119/// ParseTemplateParameterList - Parse a template parameter list. If 120/// the parsing fails badly (i.e., closing bracket was left out), this 121/// will try to put the token stream in a reasonable position (closing 122/// a statement, etc.) and return false. 123/// 124/// template-parameter-list: [C++ temp] 125/// template-parameter 126/// template-parameter-list ',' template-parameter 127bool 128Parser::ParseTemplateParameterList(unsigned Depth, 129 TemplateParameterList &TemplateParams) { 130 while(1) { 131 if (DeclTy* TmpParam 132 = ParseTemplateParameter(Depth, TemplateParams.size())) { 133 TemplateParams.push_back(TmpParam); 134 } else { 135 // If we failed to parse a template parameter, skip until we find 136 // a comma or closing brace. 137 SkipUntil(tok::comma, tok::greater, true, true); 138 } 139 140 // Did we find a comma or the end of the template parmeter list? 141 if(Tok.is(tok::comma)) { 142 ConsumeToken(); 143 } else if(Tok.is(tok::greater)) { 144 // Don't consume this... that's done by template parser. 145 break; 146 } else { 147 // Somebody probably forgot to close the template. Skip ahead and 148 // try to get out of the expression. This error is currently 149 // subsumed by whatever goes on in ParseTemplateParameter. 150 // TODO: This could match >>, and it would be nice to avoid those 151 // silly errors with template <vec<T>>. 152 // Diag(Tok.getLocation(), diag::err_expected_comma_greater); 153 SkipUntil(tok::greater, true, true); 154 return false; 155 } 156 } 157 return true; 158} 159 160/// ParseTemplateParameter - Parse a template-parameter (C++ [temp.param]). 161/// 162/// template-parameter: [C++ temp.param] 163/// type-parameter 164/// parameter-declaration 165/// 166/// type-parameter: (see below) 167/// 'class' identifier[opt] 168/// 'class' identifier[opt] '=' type-id 169/// 'typename' identifier[opt] 170/// 'typename' identifier[opt] '=' type-id 171/// 'template' '<' template-parameter-list '>' 'class' identifier[opt] 172/// 'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression 173Parser::DeclTy * 174Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) { 175 if(Tok.is(tok::kw_class) || 176 (Tok.is(tok::kw_typename) && 177 // FIXME: Next token has not been annotated! 178 NextToken().isNot(tok::annot_typename))) { 179 return ParseTypeParameter(Depth, Position); 180 } 181 182 if(Tok.is(tok::kw_template)) 183 return ParseTemplateTemplateParameter(Depth, Position); 184 185 // If it's none of the above, then it must be a parameter declaration. 186 // NOTE: This will pick up errors in the closure of the template parameter 187 // list (e.g., template < ; Check here to implement >> style closures. 188 return ParseNonTypeTemplateParameter(Depth, Position); 189} 190 191/// ParseTypeParameter - Parse a template type parameter (C++ [temp.param]). 192/// Other kinds of template parameters are parsed in 193/// ParseTemplateTemplateParameter and ParseNonTypeTemplateParameter. 194/// 195/// type-parameter: [C++ temp.param] 196/// 'class' identifier[opt] 197/// 'class' identifier[opt] '=' type-id 198/// 'typename' identifier[opt] 199/// 'typename' identifier[opt] '=' type-id 200Parser::DeclTy *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) { 201 assert((Tok.is(tok::kw_class) || Tok.is(tok::kw_typename)) && 202 "A type-parameter starts with 'class' or 'typename'"); 203 204 // Consume the 'class' or 'typename' keyword. 205 bool TypenameKeyword = Tok.is(tok::kw_typename); 206 SourceLocation KeyLoc = ConsumeToken(); 207 208 // Grab the template parameter name (if given) 209 SourceLocation NameLoc; 210 IdentifierInfo* ParamName = 0; 211 if(Tok.is(tok::identifier)) { 212 ParamName = Tok.getIdentifierInfo(); 213 NameLoc = ConsumeToken(); 214 } else if(Tok.is(tok::equal) || Tok.is(tok::comma) || 215 Tok.is(tok::greater)) { 216 // Unnamed template parameter. Don't have to do anything here, just 217 // don't consume this token. 218 } else { 219 Diag(Tok.getLocation(), diag::err_expected_ident); 220 return 0; 221 } 222 223 DeclTy *TypeParam = Actions.ActOnTypeParameter(CurScope, TypenameKeyword, 224 KeyLoc, ParamName, NameLoc, 225 Depth, Position); 226 227 // Grab a default type id (if given). 228 if(Tok.is(tok::equal)) { 229 SourceLocation EqualLoc = ConsumeToken(); 230 if (TypeTy *DefaultType = ParseTypeName()) 231 Actions.ActOnTypeParameterDefault(TypeParam, DefaultType); 232 } 233 234 return TypeParam; 235} 236 237/// ParseTemplateTemplateParameter - Handle the parsing of template 238/// template parameters. 239/// 240/// type-parameter: [C++ temp.param] 241/// 'template' '<' template-parameter-list '>' 'class' identifier[opt] 242/// 'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression 243Parser::DeclTy * 244Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) { 245 assert(Tok.is(tok::kw_template) && "Expected 'template' keyword"); 246 247 // Handle the template <...> part. 248 SourceLocation TemplateLoc = ConsumeToken(); 249 TemplateParameterList TemplateParams; 250 SourceLocation LParenLoc, RParenLoc; 251 if(!ParseTemplateParameters(Depth + 1, TemplateParams, LParenLoc, 252 RParenLoc)) { 253 return 0; 254 } 255 256 // Generate a meaningful error if the user forgot to put class before the 257 // identifier, comma, or greater. 258 if(!Tok.is(tok::kw_class)) { 259 Diag(Tok.getLocation(), diag::err_expected_class_before) 260 << PP.getSpelling(Tok); 261 return 0; 262 } 263 SourceLocation ClassLoc = ConsumeToken(); 264 265 // Get the identifier, if given. 266 SourceLocation NameLoc; 267 IdentifierInfo* ParamName = 0; 268 if(Tok.is(tok::identifier)) { 269 ParamName = Tok.getIdentifierInfo(); 270 NameLoc = ConsumeToken(); 271 } else if(Tok.is(tok::equal) || Tok.is(tok::comma) || Tok.is(tok::greater)) { 272 // Unnamed template parameter. Don't have to do anything here, just 273 // don't consume this token. 274 } else { 275 Diag(Tok.getLocation(), diag::err_expected_ident); 276 return 0; 277 } 278 279 // Get the a default value, if given. 280 // FIXME: I think that the results of this block need to be passed to the 281 // act-on call, so we can assemble the parameter correctly. 282 OwningExprResult DefaultExpr(Actions); 283 if(Tok.is(tok::equal)) { 284 ConsumeToken(); 285 DefaultExpr = ParseCXXIdExpression(); 286 if(DefaultExpr.isInvalid()) { 287 return 0; 288 } 289 } 290 291 return Actions.ActOnTemplateTemplateParameter(CurScope, TemplateLoc, 292 &TemplateParams, ParamName, 293 NameLoc, Depth, Position); 294} 295 296/// ParseNonTypeTemplateParameter - Handle the parsing of non-type 297/// template parameters (e.g., in "template<int Size> class array;"). 298/// 299/// template-parameter: 300/// ... 301/// parameter-declaration 302/// 303/// NOTE: It would be ideal to simply call out to ParseParameterDeclaration(), 304/// but that didn't work out to well. Instead, this tries to recrate the basic 305/// parsing of parameter declarations, but tries to constrain it for template 306/// parameters. 307/// FIXME: We need to make a ParseParameterDeclaration that works for 308/// non-type template parameters and normal function parameters. 309Parser::DeclTy * 310Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) { 311 SourceLocation StartLoc = Tok.getLocation(); 312 313 // Parse the declaration-specifiers (i.e., the type). 314 // FIXME: The type should probably be restricted in some way... Not all 315 // declarators (parts of declarators?) are accepted for parameters. 316 DeclSpec DS; 317 ParseDeclarationSpecifiers(DS); 318 319 // Parse this as a typename. 320 Declarator ParamDecl(DS, Declarator::TemplateParamContext); 321 ParseDeclarator(ParamDecl); 322 if (DS.getTypeSpecType() == DeclSpec::TST_unspecified && !DS.getTypeRep()) { 323 // This probably shouldn't happen - and it's more of a Sema thing, but 324 // basically we didn't parse the type name because we couldn't associate 325 // it with an AST node. we should just skip to the comma or greater. 326 // TODO: This is currently a placeholder for some kind of Sema Error. 327 Diag(Tok.getLocation(), diag::err_parse_error); 328 SkipUntil(tok::comma, tok::greater, true, true); 329 return 0; 330 } 331 332 // Create the parameter. 333 DeclTy *Param = Actions.ActOnNonTypeTemplateParameter(CurScope, ParamDecl, 334 Depth, Position); 335 336 // Is there a default value? Parsing this can be fairly annoying because 337 // we have to stop on the first non-nested (paren'd) '>' as the closure 338 // for the template parameter list. Or a ','. 339 if (Tok.is(tok::equal)) { 340 // TODO: Implement default non-type values. 341 SkipUntil(tok::comma, tok::greater, true, true); 342 } 343 344 return Param; 345} 346 347/// AnnotateTemplateIdToken - The current token is an identifier that 348/// refers to the template declaration Template, and is followed by a 349/// '<'. Turn this template-id into a template-id annotation token. 350void Parser::AnnotateTemplateIdToken(DeclTy *Template, const CXXScopeSpec *SS) { 351 assert(getLang().CPlusPlus && "Can only annotate template-ids in C++"); 352 assert(Template && Tok.is(tok::identifier) && NextToken().is(tok::less) && 353 "Parser isn't at the beginning of a template-id"); 354 355 // Consume the template-name. 356 SourceLocation TemplateNameLoc = ConsumeToken(); 357 358 // Consume the '<'. 359 SourceLocation LAngleLoc = ConsumeToken(); 360 361 // Parse the optional template-argument-list. 362 TemplateArgList TemplateArgs; 363 if (Tok.isNot(tok::greater) && ParseTemplateArgumentList(TemplateArgs)) { 364 // Try to find the closing '>'. 365 SkipUntil(tok::greater, true, true); 366 367 // FIXME: What's our recovery strategy for failed template-argument-lists? 368 return; 369 } 370 371 if (Tok.isNot(tok::greater)) 372 return; 373 374 // Determine the location of the '>'. We won't actually consume this 375 // token, because we'll be replacing it with the template-id. 376 SourceLocation RAngleLoc = Tok.getLocation(); 377 378 Tok.setKind(tok::annot_template_id); 379 Tok.setAnnotationEndLoc(RAngleLoc); 380 Tok.setLocation(TemplateNameLoc); 381 if (SS && SS->isNotEmpty()) 382 Tok.setLocation(SS->getBeginLoc()); 383 384 TemplateIdAnnotation *TemplateId 385 = (TemplateIdAnnotation *)malloc(sizeof(TemplateIdAnnotation) + 386 sizeof(TemplateArgTy*) * TemplateArgs.size()); 387 TemplateId->TemplateNameLoc = TemplateNameLoc; 388 TemplateId->Template = Template; 389 TemplateId->LAngleLoc = LAngleLoc; 390 TemplateId->NumArgs = TemplateArgs.size(); 391 TemplateArgTy **Args = (TemplateArgTy**)(TemplateId + 1); 392 for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg) 393 Args[Arg] = TemplateArgs[Arg]; 394 Tok.setAnnotationValue(TemplateId); 395 396 // In case the tokens were cached, have Preprocessor replace them with the 397 // annotation token. 398 PP.AnnotateCachedTokens(Tok); 399} 400 401/// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]). 402/// 403/// template-argument: [C++ 14.2] 404/// assignment-expression 405/// type-id 406/// id-expression 407Parser::OwningTemplateArgResult Parser::ParseTemplateArgument() { 408 // FIXME: Implement this! 409 return TemplateArgError(); 410} 411 412/// ParseTemplateArgumentList - Parse a C++ template-argument-list 413/// (C++ [temp.names]). Returns true if there was an error. 414/// 415/// template-argument-list: [C++ 14.2] 416/// template-argument 417/// template-argument-list ',' template-argument 418bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) { 419 while (true) { 420 OwningTemplateArgResult Arg = ParseTemplateArgument(); 421 if (Arg.isInvalid()) { 422 SkipUntil(tok::comma, tok::greater, true, true); 423 return true; 424 } 425 else 426 TemplateArgs.push_back(Arg.release()); 427 428 // If the next token is a comma, consume it and keep reading 429 // arguments. 430 if (Tok.isNot(tok::comma)) break; 431 432 // Consume the comma. 433 ConsumeToken(); 434 } 435 436 return Tok.isNot(tok::greater); 437} 438 439