diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 5 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 6 | ||||
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 45 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 10 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 43 |
5 files changed, 43 insertions, 66 deletions
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index ab5a3bc0b2..4eb866d688 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -44,11 +44,6 @@ TemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc, NumParams, RAngleLoc); } -void TemplateArg::Destroy(ASTContext &C) { - if (Kind == ExprArg) - getAsExpr()->Destroy(C); -} - //===----------------------------------------------------------------------===// // TemplateDecl Implementation //===----------------------------------------------------------------------===// diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 6ec5062f93..bf10b9ad70 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -925,6 +925,12 @@ ClassTemplateSpecializationType(TemplateDecl *T, unsigned NumArgs, Data[Arg] = Args[Arg]; } +void ClassTemplateSpecializationType::Destroy(ASTContext& C) { + for (unsigned Arg = 0; Arg < NumArgs; ++Arg) + if (!isArgType(Arg)) + getArgAsExpr(Arg)->Destroy(C); +} + uintptr_t ClassTemplateSpecializationType::getArgAsOpaqueValue(unsigned Arg) const { const uintptr_t *Data = reinterpret_cast<const uintptr_t *>(this + 1); diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 2e2cf5357f..f083be5602 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -368,10 +368,12 @@ void Parser::AnnotateTemplateIdToken(DeclTy *Template, TemplateNameKind TNK, SourceLocation LAngleLoc = ConsumeToken(); // Parse the optional template-argument-list. - ASTVector<&ActionBase::DeleteTemplateArg, 8> TemplateArgs(Actions); + TemplateArgList TemplateArgs; + TemplateArgIsTypeList TemplateArgIsType; { MakeGreaterThanTemplateArgumentListTerminator G(GreaterThanIsOperator); - if (Tok.isNot(tok::greater) && ParseTemplateArgumentList(TemplateArgs)) { + if (Tok.isNot(tok::greater) && + ParseTemplateArgumentList(TemplateArgs, TemplateArgIsType)) { // Try to find the closing '>'. SkipUntil(tok::greater, true, true); @@ -391,16 +393,15 @@ void Parser::AnnotateTemplateIdToken(DeclTy *Template, TemplateNameKind TNK, if (TNK == Action::TNK_Function_template) { // This is a function template. We'll be building a template-id // annotation token. - TemplateArgs.take(); // Annotation token takes ownership Tok.setKind(tok::annot_template_id); TemplateIdAnnotation *TemplateId = (TemplateIdAnnotation *)malloc(sizeof(TemplateIdAnnotation) + - sizeof(TemplateArgTy*) * TemplateArgs.size()); + sizeof(void*) * TemplateArgs.size()); TemplateId->TemplateNameLoc = TemplateNameLoc; TemplateId->Template = Template; TemplateId->LAngleLoc = LAngleLoc; TemplateId->NumArgs = TemplateArgs.size(); - TemplateArgTy **Args = (TemplateArgTy**)(TemplateId + 1); + void **Args = (void**)(TemplateId + 1); for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg) Args[Arg] = TemplateArgs[Arg]; Tok.setAnnotationValue(TemplateId); @@ -408,9 +409,12 @@ void Parser::AnnotateTemplateIdToken(DeclTy *Template, TemplateNameKind TNK, // This is a type template, e.g., a class template, template // template parameter, or template alias. We'll be building a // "typename" annotation token. + ASTTemplateArgsPtr TemplateArgsPtr(Actions, &TemplateArgs[0], + &TemplateArgIsType[0], + TemplateArgs.size()); TypeTy *Ty - = Actions.ActOnClassTemplateSpecialization(Template,LAngleLoc, - move_arg(TemplateArgs), + = Actions.ActOnClassTemplateSpecialization(Template, LAngleLoc, + TemplateArgsPtr, RAngleLoc, SS); Tok.setKind(tok::annot_typename); Tok.setAnnotationValue(Ty); @@ -433,7 +437,7 @@ void Parser::AnnotateTemplateIdToken(DeclTy *Template, TemplateNameKind TNK, /// assignment-expression /// type-id /// id-expression -Parser::OwningTemplateArgResult Parser::ParseTemplateArgument() { +void *Parser::ParseTemplateArgument(bool &ArgIsType) { // C++ [temp.arg]p2: // In a template-argument, an ambiguity between a type-id and an // expression is resolved to a type-id, regardless of the form of @@ -441,15 +445,16 @@ Parser::OwningTemplateArgResult Parser::ParseTemplateArgument() { // // Therefore, we initially try to parse a type-id. if (isTypeIdInParens()) { - TypeTy *TypeArg = ParseTypeName(); - return Actions.ActOnTypeTemplateArgument(TypeArg); + ArgIsType = true; + return ParseTypeName(); } OwningExprResult ExprArg = ParseExpression(); if (ExprArg.isInvalid()) - return TemplateArgError(); + return 0; - return Actions.ActOnExprTemplateArgument(move(ExprArg)); + ArgIsType = false; + return ExprArg.release(); } /// ParseTemplateArgumentList - Parse a C++ template-argument-list @@ -458,16 +463,20 @@ Parser::OwningTemplateArgResult Parser::ParseTemplateArgument() { /// template-argument-list: [C++ 14.2] /// template-argument /// template-argument-list ',' template-argument -bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) { +bool +Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs, + TemplateArgIsTypeList &TemplateArgIsType) { while (true) { - OwningTemplateArgResult Arg = ParseTemplateArgument(); - if (Arg.isInvalid()) { + bool IsType = false; + void *Arg = ParseTemplateArgument(IsType); + if (Arg) { + TemplateArgs.push_back(Arg); + TemplateArgIsType.push_back(IsType); + } else { SkipUntil(tok::comma, tok::greater, true, true); return true; } - else - TemplateArgs.push_back(Arg.release()); - + // If the next token is a comma, consume it and keep reading // arguments. if (Tok.isNot(tok::comma)) break; diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index bba99fd751..ca4c528d98 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -62,7 +62,6 @@ namespace clang { class TypedefDecl; class TemplateDecl; class TemplateParameterList; - class TemplateArg; class ObjCInterfaceDecl; class ObjCCompatibleAliasDecl; class ObjCProtocolDecl; @@ -259,9 +258,6 @@ public: return OwningExprResult(*this, R.get()); } OwningStmtResult Owned(Stmt* S) { return OwningStmtResult(*this, S); } - OwningTemplateArgResult Owned(TemplateArg *Arg) { - return OwningTemplateArgResult(*this, Arg); - } virtual void ActOnEndOfTranslationUnit(); @@ -1511,10 +1507,6 @@ public: DeclTy **Params, unsigned NumParams, SourceLocation RAngleLoc); - virtual OwningTemplateArgResult ActOnTypeTemplateArgument(TypeTy *Type); - - virtual OwningTemplateArgResult ActOnExprTemplateArgument(ExprArg Value); - virtual DeclTy * ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK, SourceLocation KWLoc, const CXXScopeSpec &SS, @@ -1525,7 +1517,7 @@ public: virtual TypeTy * ActOnClassTemplateSpecialization(DeclTy *Template, SourceLocation LAngleLoc, - MultiTemplateArgsArg TemplateArgs, + ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, const CXXScopeSpec *SS = 0); diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 6b6a50130a..740198b11b 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -231,15 +231,6 @@ Sema::ActOnTemplateParameterList(unsigned Depth, (Decl**)Params, NumParams, RAngleLoc); } -Sema::OwningTemplateArgResult Sema::ActOnTypeTemplateArgument(TypeTy *Type) { - return Owned(new (Context) TemplateArg(QualType::getFromOpaquePtr(Type))); -} - -Sema::OwningTemplateArgResult -Sema::ActOnExprTemplateArgument(ExprArg Value) { - return Owned(new (Context) TemplateArg(static_cast<Expr *>(Value.release()))); -} - Sema::DeclTy * Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK, SourceLocation KWLoc, const CXXScopeSpec &SS, @@ -368,37 +359,21 @@ Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK, Action::TypeTy * Sema::ActOnClassTemplateSpecialization(DeclTy *TemplateD, SourceLocation LAngleLoc, - MultiTemplateArgsArg TemplateArgsIn, + ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, const CXXScopeSpec *SS) { TemplateDecl *Template = cast<TemplateDecl>(static_cast<Decl *>(TemplateD)); - // FIXME: Not happy about this. We should teach the parser to pass - // us opaque pointers + bools for template argument lists. - // FIXME: Also not happy about the fact that we leak these - // TemplateArg structures. Fixing the above will fix this, too. - llvm::SmallVector<uintptr_t, 16> Args; - llvm::SmallVector<bool, 16> ArgIsType; - unsigned NumArgs = TemplateArgsIn.size(); - TemplateArg **TemplateArgs - = reinterpret_cast<TemplateArg **>(TemplateArgsIn.release()); - for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { - if (Expr *ExprArg = TemplateArgs[Arg]->getAsExpr()) { - Args.push_back(reinterpret_cast<uintptr_t>(ExprArg)); - ArgIsType.push_back(false); - } else { - QualType T = TemplateArgs[Arg]->getAsType(); - Args.push_back(reinterpret_cast<uintptr_t>(T.getAsOpaquePtr())); - ArgIsType.push_back(true); - } - } - // Yes, all class template specializations are just silly sugar for // 'int'. Gotta problem wit dat? - return Context.getClassTemplateSpecializationType(Template, NumArgs, - &Args[0], &ArgIsType[0], - Context.IntTy) - .getAsOpaquePtr(); + QualType Result + = Context.getClassTemplateSpecializationType(Template, + TemplateArgs.size(), + reinterpret_cast<uintptr_t *>(TemplateArgs.getArgs()), + TemplateArgs.getArgIsType(), + Context.IntTy); + TemplateArgs.release(); + return Result.getAsOpaquePtr(); } /// \brief Determine whether the given template parameter lists are |