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