summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-02-09 19:34:22 +0000
committerDouglas Gregor <dgregor@apple.com>2009-02-09 19:34:22 +0000
commit67b556a0daebd738a087a3cb47ba846230684859 (patch)
treec7aa7b20918a8293f78a30dcfa6375c27e1dd811 /clang/lib
parent8bf4205c703aecfe28a8b4e3ae796e5b40be4672 (diff)
downloadbcm5719-llvm-67b556a0daebd738a087a3cb47ba846230684859.tar.gz
bcm5719-llvm-67b556a0daebd738a087a3cb47ba846230684859.zip
Eliminate TemplateArg so that we only have a single kind of
representation for template arguments. Also simplifies the interface for ActOnClassTemplateSpecialization and eliminates some annoying allocations of TemplateArgs. My attempt at smart pointers for template arguments lists is relatively lame. We can improve it once we're sure that we have the right representation for template arguments. llvm-svn: 64154
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/DeclTemplate.cpp5
-rw-r--r--clang/lib/AST/Type.cpp6
-rw-r--r--clang/lib/Parse/ParseTemplate.cpp45
-rw-r--r--clang/lib/Sema/Sema.h10
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp43
5 files changed, 43 insertions, 66 deletions
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index ab5a3bc0b2f..4eb866d6887 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/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/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 6ec5062f93a..bf10b9ad70c 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/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/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 2e2cf5357f8..f083be56024 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/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/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index bba99fd7513..ca4c528d986 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/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/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 6b6a50130ab..740198b11bd 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/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
OpenPOWER on IntegriCloud