aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/DeclTemplate.h29
-rw-r--r--include/clang/AST/Type.h2
-rw-r--r--include/clang/Parse/Action.h25
-rw-r--r--include/clang/Parse/Ownership.h62
-rw-r--r--include/clang/Parse/Parser.h16
-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
10 files changed, 107 insertions, 136 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index daf4210c44..b466a118b1 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -336,35 +336,6 @@ protected:
friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
};
-class TemplateArg {
- enum {
- TypeArg,
- ExprArg
- } Kind;
-
- uintptr_t Ptr;
-
-public:
- explicit TemplateArg(QualType Type)
- : Kind(TypeArg), Ptr(reinterpret_cast<uintptr_t>(Type.getAsOpaquePtr())) { }
- explicit TemplateArg(Expr *E)
- : Kind(ExprArg), Ptr(reinterpret_cast<uintptr_t>(E)) { }
-
- QualType getAsType() const {
- if (Kind == TypeArg)
- return QualType::getFromOpaquePtr(reinterpret_cast<void*>(Ptr));
- return QualType();
- }
-
- Expr *getAsExpr() const {
- if (Kind == ExprArg) return reinterpret_cast<Expr *>(Ptr);
- return 0;
- }
-
- void Destroy(ASTContext &C);
-};
-
-
} /* end of namespace clang */
#endif
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 8b9826e347..1d59489864 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1440,6 +1440,8 @@ class ClassTemplateSpecializationType
static void
packBooleanValues(unsigned NumArgs, bool *Values, uintptr_t *Words);
+ virtual void Destroy(ASTContext& C);
+
friend class ASTContext; // ASTContext creates these
public:
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index b13b8ef228..14b2cea81a 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -74,7 +74,6 @@ public:
typedef void MemInitTy;
typedef void CXXScopeTy;
typedef void TemplateParamsTy;
- typedef void TemplateArgTy;
/// Expr/Stmt/Type/BaseResult - Provide a unique type to wrap
/// ExprTy/StmtTy/TypeTy/BaseTy, providing strong typing and
@@ -88,8 +87,6 @@ public:
/// Same, but with ownership.
typedef ASTOwningResult<&ActionBase::DeleteExpr> OwningExprResult;
typedef ASTOwningResult<&ActionBase::DeleteStmt> OwningStmtResult;
- typedef ASTOwningResult<&ActionBase::DeleteTemplateArg>
- OwningTemplateArgResult;
// Note that these will replace ExprResult and StmtResult when the transition
// is complete.
@@ -97,38 +94,26 @@ public:
#if !defined(DISABLE_SMART_POINTERS)
typedef ASTOwningResult<&ActionBase::DeleteExpr> ExprArg;
typedef ASTOwningResult<&ActionBase::DeleteStmt> StmtArg;
- typedef ASTOwningResult<&ActionBase::DeleteTemplateArg> TemplateArgArg;
#else
typedef ASTOwningPtr<&ActionBase::DeleteExpr> ExprArg;
typedef ASTOwningPtr<&ActionBase::DeleteStmt> StmtArg;
- typedef ASTOwningPtr<&ActionBase::DeleteTemplateArg> TemplateArgArg;
#endif
/// Multiple expressions or statements as arguments.
typedef ASTMultiPtr<&ActionBase::DeleteExpr> MultiExprArg;
typedef ASTMultiPtr<&ActionBase::DeleteStmt> MultiStmtArg;
typedef ASTMultiPtr<&ActionBase::DeleteTemplateParams> MultiTemplateParamsArg;
- typedef ASTMultiPtr<&ActionBase::DeleteTemplateArg> MultiTemplateArgsArg;
// Utilities for Action implementations to return smart results.
OwningExprResult ExprError() { return OwningExprResult(*this, true); }
OwningStmtResult StmtError() { return OwningStmtResult(*this, true); }
- OwningTemplateArgResult TemplateArgError() {
- return OwningTemplateArgResult(*this, true);
- }
OwningExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); }
OwningStmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); }
- OwningTemplateArgResult TemplateArgError(const DiagnosticBuilder&) {
- return TemplateArgError();
- }
OwningExprResult ExprEmpty() { return OwningExprResult(*this, false); }
OwningStmtResult StmtEmpty() { return OwningStmtResult(*this, false); }
- OwningTemplateArgResult TemplateArgEmpty() {
- return OwningTemplateArgResult(*this, false);
- }
/// Statistics.
virtual void PrintStats() const {}
@@ -1126,14 +1111,6 @@ public:
return 0;
}
- virtual OwningTemplateArgResult ActOnTypeTemplateArgument(TypeTy *Type) {
- return TemplateArgError();
- }
-
- virtual OwningTemplateArgResult ActOnExprTemplateArgument(ExprArg Value) {
- return TemplateArgError();
- }
-
/// \brief Process the declaration or definition of a class template
/// with the given template parameter lists.
virtual DeclTy *
@@ -1158,7 +1135,7 @@ public:
virtual TypeTy *
ActOnClassTemplateSpecialization(DeclTy *Template,
SourceLocation LAngleLoc,
- MultiTemplateArgsArg TemplateArgs,
+ ASTTemplateArgsPtr TemplateArgs,
SourceLocation RAngleLoc,
const CXXScopeSpec *SS = 0) {
return 0;
diff --git a/include/clang/Parse/Ownership.h b/include/clang/Parse/Ownership.h
index 6017db761f..f191d9a3b4 100644
--- a/include/clang/Parse/Ownership.h
+++ b/include/clang/Parse/Ownership.h
@@ -132,7 +132,6 @@ namespace clang
typedef void ExprTy;
typedef void StmtTy;
typedef void TemplateParamsTy;
- typedef void TemplateArgTy;
/// ActionResult - This structure is used while parsing/acting on
/// expressions, stmts, etc. It encapsulates both the object returned by
@@ -207,7 +206,6 @@ namespace clang
virtual void DeleteExpr(ExprTy *E) {}
virtual void DeleteStmt(StmtTy *E) {}
virtual void DeleteTemplateParams(TemplateParamsTy *E) {}
- virtual void DeleteTemplateArg(TemplateArgTy *E) {}
};
/// ASTDestroyer - The type of an AST node destruction function pointer.
@@ -222,10 +220,6 @@ namespace clang
template <> struct DestroyerToUID<&ActionBase::DeleteStmt> {
static const unsigned UID = 1;
};
- template <> struct DestroyerToUID<&ActionBase::DeleteTemplateArg> {
- static const unsigned UID = 5; // FIXME
- };
-
/// ASTOwningResult - A moveable smart pointer for AST nodes that also
/// has an extra flag to indicate an additional success status.
template <ASTDestroyer Destroyer> class ASTOwningResult;
@@ -536,6 +530,62 @@ namespace clang
}
#endif
};
+
+ class ASTTemplateArgsPtr {
+#if !defined(DISABLE_SMART_POINTERS)
+ ActionBase &Actions;
+#endif
+ void **Args;
+ bool *ArgIsType;
+ mutable unsigned Count;
+
+#if !defined(DISABLE_SMART_POINTERS)
+ void destroy() {
+ if (!Count)
+ return;
+
+ for (unsigned i = 0; i != Count; ++i)
+ if (Args[i] && !ArgIsType[i])
+ Actions.DeleteExpr((ActionBase::ExprTy *)Args[i]);
+
+ Count = 0;
+ }
+#endif
+
+ public:
+ ASTTemplateArgsPtr(ActionBase &actions, void **args, bool *argIsType,
+ unsigned count) :
+#if !defined(DISABLE_SMART_POINTERS)
+ Actions(actions),
+#endif
+ Args(args), ArgIsType(argIsType), Count(count) { }
+
+ // FIXME: Lame, not-fully-type-safe emulation of 'move semantics'.
+ ASTTemplateArgsPtr(ASTTemplateArgsPtr &Other) :
+#if !defined(DISABLE_SMART_POINTERS)
+ Actions(Other.Actions),
+#endif
+ Args(Other.Args), ArgIsType(Other.ArgIsType), Count(Other.Count) {
+#if !defined(DISABLE_SMART_POINTERS)
+ Other.destroy();
+#endif
+ }
+
+#if !defined(DISABLE_SMART_POINTERS)
+ ~ASTTemplateArgsPtr() { destroy(); }
+#endif
+
+ void **getArgs() const { return Args; }
+ bool *getArgIsType() const {return ArgIsType; }
+ unsigned size() const { return Count; }
+
+ void **release() const {
+#if !defined(DISABLE_SMART_POINTERS)
+ Count = 0;
+#endif
+ return Args;
+ }
+ };
#if !defined(DISABLE_SMART_POINTERS)
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 7a73fcba53..a197f2c035 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -114,7 +114,6 @@ public:
typedef Action::MemInitTy MemInitTy;
typedef Action::CXXScopeTy CXXScopeTy;
typedef Action::TemplateParamsTy TemplateParamsTy;
- typedef Action::TemplateArgTy TemplateArgTy;
typedef llvm::SmallVector<TemplateParamsTy *, 4> TemplateParameterLists;
@@ -125,7 +124,6 @@ public:
typedef Action::OwningExprResult OwningExprResult;
typedef Action::OwningStmtResult OwningStmtResult;
- typedef Action::OwningTemplateArgResult OwningTemplateArgResult;
typedef Action::ExprArg ExprArg;
typedef Action::MultiStmtArg MultiStmtArg;
@@ -141,15 +139,9 @@ public:
OwningExprResult ExprError() { return OwningExprResult(Actions, true); }
OwningStmtResult StmtError() { return OwningStmtResult(Actions, true); }
- OwningTemplateArgResult TemplateArgError() {
- return OwningTemplateArgResult(Actions, true);
- }
OwningExprResult ExprError(const DiagnosticBuilder &) { return ExprError(); }
OwningStmtResult StmtError(const DiagnosticBuilder &) { return StmtError(); }
- OwningTemplateArgResult TemplateArgError(const DiagnosticBuilder &) {
- return TemplateArgError();
- }
// Parsing methods.
@@ -1029,11 +1021,13 @@ private:
DeclTy *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
DeclTy *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
// C++ 14.3: Template arguments [temp.arg]
- typedef llvm::SmallVector<TemplateArgTy*, 8> TemplateArgList;
+ typedef llvm::SmallVector<void *, 16> TemplateArgList;
+ typedef llvm::SmallVector<bool, 16> TemplateArgIsTypeList;
void AnnotateTemplateIdToken(DeclTy *Template, TemplateNameKind TNK,
const CXXScopeSpec *SS = 0);
- bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
- OwningTemplateArgResult ParseTemplateArgument();
+ bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
+ TemplateArgIsTypeList &TemplateArgIsType);
+ void *ParseTemplateArgument(bool &ArgIsType);
//===--------------------------------------------------------------------===//
// GNU G++: Type Traits [Type-Traits.html in the GCC manual]
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