forked from OSchip/llvm-project
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
This commit is contained in:
parent
8bf4205c70
commit
67b556a0da
|
@ -336,35 +336,6 @@ protected:
|
||||||
friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
|
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 */
|
} /* end of namespace clang */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1440,6 +1440,8 @@ class ClassTemplateSpecializationType
|
||||||
static void
|
static void
|
||||||
packBooleanValues(unsigned NumArgs, bool *Values, uintptr_t *Words);
|
packBooleanValues(unsigned NumArgs, bool *Values, uintptr_t *Words);
|
||||||
|
|
||||||
|
virtual void Destroy(ASTContext& C);
|
||||||
|
|
||||||
friend class ASTContext; // ASTContext creates these
|
friend class ASTContext; // ASTContext creates these
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -74,7 +74,6 @@ public:
|
||||||
typedef void MemInitTy;
|
typedef void MemInitTy;
|
||||||
typedef void CXXScopeTy;
|
typedef void CXXScopeTy;
|
||||||
typedef void TemplateParamsTy;
|
typedef void TemplateParamsTy;
|
||||||
typedef void TemplateArgTy;
|
|
||||||
|
|
||||||
/// Expr/Stmt/Type/BaseResult - Provide a unique type to wrap
|
/// Expr/Stmt/Type/BaseResult - Provide a unique type to wrap
|
||||||
/// ExprTy/StmtTy/TypeTy/BaseTy, providing strong typing and
|
/// ExprTy/StmtTy/TypeTy/BaseTy, providing strong typing and
|
||||||
|
@ -88,8 +87,6 @@ public:
|
||||||
/// Same, but with ownership.
|
/// Same, but with ownership.
|
||||||
typedef ASTOwningResult<&ActionBase::DeleteExpr> OwningExprResult;
|
typedef ASTOwningResult<&ActionBase::DeleteExpr> OwningExprResult;
|
||||||
typedef ASTOwningResult<&ActionBase::DeleteStmt> OwningStmtResult;
|
typedef ASTOwningResult<&ActionBase::DeleteStmt> OwningStmtResult;
|
||||||
typedef ASTOwningResult<&ActionBase::DeleteTemplateArg>
|
|
||||||
OwningTemplateArgResult;
|
|
||||||
// Note that these will replace ExprResult and StmtResult when the transition
|
// Note that these will replace ExprResult and StmtResult when the transition
|
||||||
// is complete.
|
// is complete.
|
||||||
|
|
||||||
|
@ -97,38 +94,26 @@ public:
|
||||||
#if !defined(DISABLE_SMART_POINTERS)
|
#if !defined(DISABLE_SMART_POINTERS)
|
||||||
typedef ASTOwningResult<&ActionBase::DeleteExpr> ExprArg;
|
typedef ASTOwningResult<&ActionBase::DeleteExpr> ExprArg;
|
||||||
typedef ASTOwningResult<&ActionBase::DeleteStmt> StmtArg;
|
typedef ASTOwningResult<&ActionBase::DeleteStmt> StmtArg;
|
||||||
typedef ASTOwningResult<&ActionBase::DeleteTemplateArg> TemplateArgArg;
|
|
||||||
#else
|
#else
|
||||||
typedef ASTOwningPtr<&ActionBase::DeleteExpr> ExprArg;
|
typedef ASTOwningPtr<&ActionBase::DeleteExpr> ExprArg;
|
||||||
typedef ASTOwningPtr<&ActionBase::DeleteStmt> StmtArg;
|
typedef ASTOwningPtr<&ActionBase::DeleteStmt> StmtArg;
|
||||||
typedef ASTOwningPtr<&ActionBase::DeleteTemplateArg> TemplateArgArg;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Multiple expressions or statements as arguments.
|
/// Multiple expressions or statements as arguments.
|
||||||
typedef ASTMultiPtr<&ActionBase::DeleteExpr> MultiExprArg;
|
typedef ASTMultiPtr<&ActionBase::DeleteExpr> MultiExprArg;
|
||||||
typedef ASTMultiPtr<&ActionBase::DeleteStmt> MultiStmtArg;
|
typedef ASTMultiPtr<&ActionBase::DeleteStmt> MultiStmtArg;
|
||||||
typedef ASTMultiPtr<&ActionBase::DeleteTemplateParams> MultiTemplateParamsArg;
|
typedef ASTMultiPtr<&ActionBase::DeleteTemplateParams> MultiTemplateParamsArg;
|
||||||
typedef ASTMultiPtr<&ActionBase::DeleteTemplateArg> MultiTemplateArgsArg;
|
|
||||||
|
|
||||||
// Utilities for Action implementations to return smart results.
|
// Utilities for Action implementations to return smart results.
|
||||||
|
|
||||||
OwningExprResult ExprError() { return OwningExprResult(*this, true); }
|
OwningExprResult ExprError() { return OwningExprResult(*this, true); }
|
||||||
OwningStmtResult StmtError() { return OwningStmtResult(*this, true); }
|
OwningStmtResult StmtError() { return OwningStmtResult(*this, true); }
|
||||||
OwningTemplateArgResult TemplateArgError() {
|
|
||||||
return OwningTemplateArgResult(*this, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
OwningExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); }
|
OwningExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); }
|
||||||
OwningStmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); }
|
OwningStmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); }
|
||||||
OwningTemplateArgResult TemplateArgError(const DiagnosticBuilder&) {
|
|
||||||
return TemplateArgError();
|
|
||||||
}
|
|
||||||
|
|
||||||
OwningExprResult ExprEmpty() { return OwningExprResult(*this, false); }
|
OwningExprResult ExprEmpty() { return OwningExprResult(*this, false); }
|
||||||
OwningStmtResult StmtEmpty() { return OwningStmtResult(*this, false); }
|
OwningStmtResult StmtEmpty() { return OwningStmtResult(*this, false); }
|
||||||
OwningTemplateArgResult TemplateArgEmpty() {
|
|
||||||
return OwningTemplateArgResult(*this, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Statistics.
|
/// Statistics.
|
||||||
virtual void PrintStats() const {}
|
virtual void PrintStats() const {}
|
||||||
|
@ -1126,14 +1111,6 @@ public:
|
||||||
return 0;
|
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
|
/// \brief Process the declaration or definition of a class template
|
||||||
/// with the given template parameter lists.
|
/// with the given template parameter lists.
|
||||||
virtual DeclTy *
|
virtual DeclTy *
|
||||||
|
@ -1158,7 +1135,7 @@ public:
|
||||||
virtual TypeTy *
|
virtual TypeTy *
|
||||||
ActOnClassTemplateSpecialization(DeclTy *Template,
|
ActOnClassTemplateSpecialization(DeclTy *Template,
|
||||||
SourceLocation LAngleLoc,
|
SourceLocation LAngleLoc,
|
||||||
MultiTemplateArgsArg TemplateArgs,
|
ASTTemplateArgsPtr TemplateArgs,
|
||||||
SourceLocation RAngleLoc,
|
SourceLocation RAngleLoc,
|
||||||
const CXXScopeSpec *SS = 0) {
|
const CXXScopeSpec *SS = 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -132,7 +132,6 @@ namespace clang
|
||||||
typedef void ExprTy;
|
typedef void ExprTy;
|
||||||
typedef void StmtTy;
|
typedef void StmtTy;
|
||||||
typedef void TemplateParamsTy;
|
typedef void TemplateParamsTy;
|
||||||
typedef void TemplateArgTy;
|
|
||||||
|
|
||||||
/// ActionResult - This structure is used while parsing/acting on
|
/// ActionResult - This structure is used while parsing/acting on
|
||||||
/// expressions, stmts, etc. It encapsulates both the object returned by
|
/// expressions, stmts, etc. It encapsulates both the object returned by
|
||||||
|
@ -207,7 +206,6 @@ namespace clang
|
||||||
virtual void DeleteExpr(ExprTy *E) {}
|
virtual void DeleteExpr(ExprTy *E) {}
|
||||||
virtual void DeleteStmt(StmtTy *E) {}
|
virtual void DeleteStmt(StmtTy *E) {}
|
||||||
virtual void DeleteTemplateParams(TemplateParamsTy *E) {}
|
virtual void DeleteTemplateParams(TemplateParamsTy *E) {}
|
||||||
virtual void DeleteTemplateArg(TemplateArgTy *E) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// ASTDestroyer - The type of an AST node destruction function pointer.
|
/// ASTDestroyer - The type of an AST node destruction function pointer.
|
||||||
|
@ -222,10 +220,6 @@ namespace clang
|
||||||
template <> struct DestroyerToUID<&ActionBase::DeleteStmt> {
|
template <> struct DestroyerToUID<&ActionBase::DeleteStmt> {
|
||||||
static const unsigned UID = 1;
|
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
|
/// ASTOwningResult - A moveable smart pointer for AST nodes that also
|
||||||
/// has an extra flag to indicate an additional success status.
|
/// has an extra flag to indicate an additional success status.
|
||||||
template <ASTDestroyer Destroyer> class ASTOwningResult;
|
template <ASTDestroyer Destroyer> class ASTOwningResult;
|
||||||
|
@ -536,6 +530,62 @@ namespace clang
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
#if !defined(DISABLE_SMART_POINTERS)
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,6 @@ public:
|
||||||
typedef Action::MemInitTy MemInitTy;
|
typedef Action::MemInitTy MemInitTy;
|
||||||
typedef Action::CXXScopeTy CXXScopeTy;
|
typedef Action::CXXScopeTy CXXScopeTy;
|
||||||
typedef Action::TemplateParamsTy TemplateParamsTy;
|
typedef Action::TemplateParamsTy TemplateParamsTy;
|
||||||
typedef Action::TemplateArgTy TemplateArgTy;
|
|
||||||
|
|
||||||
typedef llvm::SmallVector<TemplateParamsTy *, 4> TemplateParameterLists;
|
typedef llvm::SmallVector<TemplateParamsTy *, 4> TemplateParameterLists;
|
||||||
|
|
||||||
|
@ -125,7 +124,6 @@ public:
|
||||||
|
|
||||||
typedef Action::OwningExprResult OwningExprResult;
|
typedef Action::OwningExprResult OwningExprResult;
|
||||||
typedef Action::OwningStmtResult OwningStmtResult;
|
typedef Action::OwningStmtResult OwningStmtResult;
|
||||||
typedef Action::OwningTemplateArgResult OwningTemplateArgResult;
|
|
||||||
|
|
||||||
typedef Action::ExprArg ExprArg;
|
typedef Action::ExprArg ExprArg;
|
||||||
typedef Action::MultiStmtArg MultiStmtArg;
|
typedef Action::MultiStmtArg MultiStmtArg;
|
||||||
|
@ -141,15 +139,9 @@ public:
|
||||||
|
|
||||||
OwningExprResult ExprError() { return OwningExprResult(Actions, true); }
|
OwningExprResult ExprError() { return OwningExprResult(Actions, true); }
|
||||||
OwningStmtResult StmtError() { return OwningStmtResult(Actions, true); }
|
OwningStmtResult StmtError() { return OwningStmtResult(Actions, true); }
|
||||||
OwningTemplateArgResult TemplateArgError() {
|
|
||||||
return OwningTemplateArgResult(Actions, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
OwningExprResult ExprError(const DiagnosticBuilder &) { return ExprError(); }
|
OwningExprResult ExprError(const DiagnosticBuilder &) { return ExprError(); }
|
||||||
OwningStmtResult StmtError(const DiagnosticBuilder &) { return StmtError(); }
|
OwningStmtResult StmtError(const DiagnosticBuilder &) { return StmtError(); }
|
||||||
OwningTemplateArgResult TemplateArgError(const DiagnosticBuilder &) {
|
|
||||||
return TemplateArgError();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parsing methods.
|
// Parsing methods.
|
||||||
|
|
||||||
|
@ -1029,11 +1021,13 @@ private:
|
||||||
DeclTy *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
|
DeclTy *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
|
||||||
DeclTy *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
|
DeclTy *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
|
||||||
// C++ 14.3: Template arguments [temp.arg]
|
// 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,
|
void AnnotateTemplateIdToken(DeclTy *Template, TemplateNameKind TNK,
|
||||||
const CXXScopeSpec *SS = 0);
|
const CXXScopeSpec *SS = 0);
|
||||||
bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
|
bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
|
||||||
OwningTemplateArgResult ParseTemplateArgument();
|
TemplateArgIsTypeList &TemplateArgIsType);
|
||||||
|
void *ParseTemplateArgument(bool &ArgIsType);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// GNU G++: Type Traits [Type-Traits.html in the GCC manual]
|
// GNU G++: Type Traits [Type-Traits.html in the GCC manual]
|
||||||
|
|
|
@ -44,11 +44,6 @@ TemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc,
|
||||||
NumParams, RAngleLoc);
|
NumParams, RAngleLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TemplateArg::Destroy(ASTContext &C) {
|
|
||||||
if (Kind == ExprArg)
|
|
||||||
getAsExpr()->Destroy(C);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// TemplateDecl Implementation
|
// TemplateDecl Implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -925,6 +925,12 @@ ClassTemplateSpecializationType(TemplateDecl *T, unsigned NumArgs,
|
||||||
Data[Arg] = Args[Arg];
|
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
|
uintptr_t
|
||||||
ClassTemplateSpecializationType::getArgAsOpaqueValue(unsigned Arg) const {
|
ClassTemplateSpecializationType::getArgAsOpaqueValue(unsigned Arg) const {
|
||||||
const uintptr_t *Data = reinterpret_cast<const uintptr_t *>(this + 1);
|
const uintptr_t *Data = reinterpret_cast<const uintptr_t *>(this + 1);
|
||||||
|
|
|
@ -368,10 +368,12 @@ void Parser::AnnotateTemplateIdToken(DeclTy *Template, TemplateNameKind TNK,
|
||||||
SourceLocation LAngleLoc = ConsumeToken();
|
SourceLocation LAngleLoc = ConsumeToken();
|
||||||
|
|
||||||
// Parse the optional template-argument-list.
|
// Parse the optional template-argument-list.
|
||||||
ASTVector<&ActionBase::DeleteTemplateArg, 8> TemplateArgs(Actions);
|
TemplateArgList TemplateArgs;
|
||||||
|
TemplateArgIsTypeList TemplateArgIsType;
|
||||||
{
|
{
|
||||||
MakeGreaterThanTemplateArgumentListTerminator G(GreaterThanIsOperator);
|
MakeGreaterThanTemplateArgumentListTerminator G(GreaterThanIsOperator);
|
||||||
if (Tok.isNot(tok::greater) && ParseTemplateArgumentList(TemplateArgs)) {
|
if (Tok.isNot(tok::greater) &&
|
||||||
|
ParseTemplateArgumentList(TemplateArgs, TemplateArgIsType)) {
|
||||||
// Try to find the closing '>'.
|
// Try to find the closing '>'.
|
||||||
SkipUntil(tok::greater, true, true);
|
SkipUntil(tok::greater, true, true);
|
||||||
|
|
||||||
|
@ -391,16 +393,15 @@ void Parser::AnnotateTemplateIdToken(DeclTy *Template, TemplateNameKind TNK,
|
||||||
if (TNK == Action::TNK_Function_template) {
|
if (TNK == Action::TNK_Function_template) {
|
||||||
// This is a function template. We'll be building a template-id
|
// This is a function template. We'll be building a template-id
|
||||||
// annotation token.
|
// annotation token.
|
||||||
TemplateArgs.take(); // Annotation token takes ownership
|
|
||||||
Tok.setKind(tok::annot_template_id);
|
Tok.setKind(tok::annot_template_id);
|
||||||
TemplateIdAnnotation *TemplateId
|
TemplateIdAnnotation *TemplateId
|
||||||
= (TemplateIdAnnotation *)malloc(sizeof(TemplateIdAnnotation) +
|
= (TemplateIdAnnotation *)malloc(sizeof(TemplateIdAnnotation) +
|
||||||
sizeof(TemplateArgTy*) * TemplateArgs.size());
|
sizeof(void*) * TemplateArgs.size());
|
||||||
TemplateId->TemplateNameLoc = TemplateNameLoc;
|
TemplateId->TemplateNameLoc = TemplateNameLoc;
|
||||||
TemplateId->Template = Template;
|
TemplateId->Template = Template;
|
||||||
TemplateId->LAngleLoc = LAngleLoc;
|
TemplateId->LAngleLoc = LAngleLoc;
|
||||||
TemplateId->NumArgs = TemplateArgs.size();
|
TemplateId->NumArgs = TemplateArgs.size();
|
||||||
TemplateArgTy **Args = (TemplateArgTy**)(TemplateId + 1);
|
void **Args = (void**)(TemplateId + 1);
|
||||||
for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg)
|
for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg)
|
||||||
Args[Arg] = TemplateArgs[Arg];
|
Args[Arg] = TemplateArgs[Arg];
|
||||||
Tok.setAnnotationValue(TemplateId);
|
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
|
// This is a type template, e.g., a class template, template
|
||||||
// template parameter, or template alias. We'll be building a
|
// template parameter, or template alias. We'll be building a
|
||||||
// "typename" annotation token.
|
// "typename" annotation token.
|
||||||
|
ASTTemplateArgsPtr TemplateArgsPtr(Actions, &TemplateArgs[0],
|
||||||
|
&TemplateArgIsType[0],
|
||||||
|
TemplateArgs.size());
|
||||||
TypeTy *Ty
|
TypeTy *Ty
|
||||||
= Actions.ActOnClassTemplateSpecialization(Template,LAngleLoc,
|
= Actions.ActOnClassTemplateSpecialization(Template, LAngleLoc,
|
||||||
move_arg(TemplateArgs),
|
TemplateArgsPtr,
|
||||||
RAngleLoc, SS);
|
RAngleLoc, SS);
|
||||||
Tok.setKind(tok::annot_typename);
|
Tok.setKind(tok::annot_typename);
|
||||||
Tok.setAnnotationValue(Ty);
|
Tok.setAnnotationValue(Ty);
|
||||||
|
@ -433,7 +437,7 @@ void Parser::AnnotateTemplateIdToken(DeclTy *Template, TemplateNameKind TNK,
|
||||||
/// assignment-expression
|
/// assignment-expression
|
||||||
/// type-id
|
/// type-id
|
||||||
/// id-expression
|
/// id-expression
|
||||||
Parser::OwningTemplateArgResult Parser::ParseTemplateArgument() {
|
void *Parser::ParseTemplateArgument(bool &ArgIsType) {
|
||||||
// C++ [temp.arg]p2:
|
// C++ [temp.arg]p2:
|
||||||
// In a template-argument, an ambiguity between a type-id and an
|
// In a template-argument, an ambiguity between a type-id and an
|
||||||
// expression is resolved to a type-id, regardless of the form of
|
// 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.
|
// Therefore, we initially try to parse a type-id.
|
||||||
if (isTypeIdInParens()) {
|
if (isTypeIdInParens()) {
|
||||||
TypeTy *TypeArg = ParseTypeName();
|
ArgIsType = true;
|
||||||
return Actions.ActOnTypeTemplateArgument(TypeArg);
|
return ParseTypeName();
|
||||||
}
|
}
|
||||||
|
|
||||||
OwningExprResult ExprArg = ParseExpression();
|
OwningExprResult ExprArg = ParseExpression();
|
||||||
if (ExprArg.isInvalid())
|
if (ExprArg.isInvalid())
|
||||||
return TemplateArgError();
|
return 0;
|
||||||
|
|
||||||
return Actions.ActOnExprTemplateArgument(move(ExprArg));
|
ArgIsType = false;
|
||||||
|
return ExprArg.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseTemplateArgumentList - Parse a C++ template-argument-list
|
/// ParseTemplateArgumentList - Parse a C++ template-argument-list
|
||||||
|
@ -458,16 +463,20 @@ Parser::OwningTemplateArgResult Parser::ParseTemplateArgument() {
|
||||||
/// template-argument-list: [C++ 14.2]
|
/// template-argument-list: [C++ 14.2]
|
||||||
/// template-argument
|
/// template-argument
|
||||||
/// template-argument-list ',' template-argument
|
/// template-argument-list ',' template-argument
|
||||||
bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
|
bool
|
||||||
|
Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
|
||||||
|
TemplateArgIsTypeList &TemplateArgIsType) {
|
||||||
while (true) {
|
while (true) {
|
||||||
OwningTemplateArgResult Arg = ParseTemplateArgument();
|
bool IsType = false;
|
||||||
if (Arg.isInvalid()) {
|
void *Arg = ParseTemplateArgument(IsType);
|
||||||
|
if (Arg) {
|
||||||
|
TemplateArgs.push_back(Arg);
|
||||||
|
TemplateArgIsType.push_back(IsType);
|
||||||
|
} else {
|
||||||
SkipUntil(tok::comma, tok::greater, true, true);
|
SkipUntil(tok::comma, tok::greater, true, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
TemplateArgs.push_back(Arg.release());
|
|
||||||
|
|
||||||
// If the next token is a comma, consume it and keep reading
|
// If the next token is a comma, consume it and keep reading
|
||||||
// arguments.
|
// arguments.
|
||||||
if (Tok.isNot(tok::comma)) break;
|
if (Tok.isNot(tok::comma)) break;
|
||||||
|
|
|
@ -62,7 +62,6 @@ namespace clang {
|
||||||
class TypedefDecl;
|
class TypedefDecl;
|
||||||
class TemplateDecl;
|
class TemplateDecl;
|
||||||
class TemplateParameterList;
|
class TemplateParameterList;
|
||||||
class TemplateArg;
|
|
||||||
class ObjCInterfaceDecl;
|
class ObjCInterfaceDecl;
|
||||||
class ObjCCompatibleAliasDecl;
|
class ObjCCompatibleAliasDecl;
|
||||||
class ObjCProtocolDecl;
|
class ObjCProtocolDecl;
|
||||||
|
@ -259,9 +258,6 @@ public:
|
||||||
return OwningExprResult(*this, R.get());
|
return OwningExprResult(*this, R.get());
|
||||||
}
|
}
|
||||||
OwningStmtResult Owned(Stmt* S) { return OwningStmtResult(*this, S); }
|
OwningStmtResult Owned(Stmt* S) { return OwningStmtResult(*this, S); }
|
||||||
OwningTemplateArgResult Owned(TemplateArg *Arg) {
|
|
||||||
return OwningTemplateArgResult(*this, Arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void ActOnEndOfTranslationUnit();
|
virtual void ActOnEndOfTranslationUnit();
|
||||||
|
|
||||||
|
@ -1511,10 +1507,6 @@ public:
|
||||||
DeclTy **Params, unsigned NumParams,
|
DeclTy **Params, unsigned NumParams,
|
||||||
SourceLocation RAngleLoc);
|
SourceLocation RAngleLoc);
|
||||||
|
|
||||||
virtual OwningTemplateArgResult ActOnTypeTemplateArgument(TypeTy *Type);
|
|
||||||
|
|
||||||
virtual OwningTemplateArgResult ActOnExprTemplateArgument(ExprArg Value);
|
|
||||||
|
|
||||||
virtual DeclTy *
|
virtual DeclTy *
|
||||||
ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
|
ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
|
||||||
SourceLocation KWLoc, const CXXScopeSpec &SS,
|
SourceLocation KWLoc, const CXXScopeSpec &SS,
|
||||||
|
@ -1525,7 +1517,7 @@ public:
|
||||||
virtual TypeTy *
|
virtual TypeTy *
|
||||||
ActOnClassTemplateSpecialization(DeclTy *Template,
|
ActOnClassTemplateSpecialization(DeclTy *Template,
|
||||||
SourceLocation LAngleLoc,
|
SourceLocation LAngleLoc,
|
||||||
MultiTemplateArgsArg TemplateArgs,
|
ASTTemplateArgsPtr TemplateArgs,
|
||||||
SourceLocation RAngleLoc,
|
SourceLocation RAngleLoc,
|
||||||
const CXXScopeSpec *SS = 0);
|
const CXXScopeSpec *SS = 0);
|
||||||
|
|
||||||
|
|
|
@ -231,15 +231,6 @@ Sema::ActOnTemplateParameterList(unsigned Depth,
|
||||||
(Decl**)Params, NumParams, RAngleLoc);
|
(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::DeclTy *
|
||||||
Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
|
Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
|
||||||
SourceLocation KWLoc, const CXXScopeSpec &SS,
|
SourceLocation KWLoc, const CXXScopeSpec &SS,
|
||||||
|
@ -368,37 +359,21 @@ Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK,
|
||||||
Action::TypeTy *
|
Action::TypeTy *
|
||||||
Sema::ActOnClassTemplateSpecialization(DeclTy *TemplateD,
|
Sema::ActOnClassTemplateSpecialization(DeclTy *TemplateD,
|
||||||
SourceLocation LAngleLoc,
|
SourceLocation LAngleLoc,
|
||||||
MultiTemplateArgsArg TemplateArgsIn,
|
ASTTemplateArgsPtr TemplateArgs,
|
||||||
SourceLocation RAngleLoc,
|
SourceLocation RAngleLoc,
|
||||||
const CXXScopeSpec *SS) {
|
const CXXScopeSpec *SS) {
|
||||||
TemplateDecl *Template = cast<TemplateDecl>(static_cast<Decl *>(TemplateD));
|
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
|
// Yes, all class template specializations are just silly sugar for
|
||||||
// 'int'. Gotta problem wit dat?
|
// 'int'. Gotta problem wit dat?
|
||||||
return Context.getClassTemplateSpecializationType(Template, NumArgs,
|
QualType Result
|
||||||
&Args[0], &ArgIsType[0],
|
= Context.getClassTemplateSpecializationType(Template,
|
||||||
Context.IntTy)
|
TemplateArgs.size(),
|
||||||
.getAsOpaquePtr();
|
reinterpret_cast<uintptr_t *>(TemplateArgs.getArgs()),
|
||||||
|
TemplateArgs.getArgIsType(),
|
||||||
|
Context.IntTy);
|
||||||
|
TemplateArgs.release();
|
||||||
|
return Result.getAsOpaquePtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Determine whether the given template parameter lists are
|
/// \brief Determine whether the given template parameter lists are
|
||||||
|
|
Loading…
Reference in New Issue