aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/DeclTemplate.cpp5
-rw-r--r--lib/AST/Type.cpp6
-rw-r--r--lib/Parse/ParseTemplate.cpp45
-rw-r--r--lib/Sema/Sema.h10
-rw-r--r--lib/Sema/SemaTemplate.cpp43
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