forked from OSchip/llvm-project
Improve parsing of template arguments to lay the foundation for
handling template template parameters properly. This refactoring: - Parses template template arguments as id-expressions, representing the result of the parse as a template name (Action::TemplateTy) rather than as an expression (lame!). - Represents all parsed template arguments via a new parser-specific type, ParsedTemplateArgument, which stores the kind of template argument (type, non-type, template) along with all of the source information about the template argument. This replaces an ad hoc set of 3 vectors (one for a void*, which was either a type or an expression; one for a bit telling whether the first was a type or an expression; and one for a single source location pointing at the template argument). - Moves TemplateIdAnnotation into the new Parse/Template.h. It never belonged in the Basic library anyway. llvm-svn: 86708
This commit is contained in:
parent
e034867587
commit
b53edfb8dc
|
@ -248,69 +248,6 @@ struct PPConditionalInfo {
|
|||
bool FoundElse;
|
||||
};
|
||||
|
||||
/// TemplateIdAnnotation - Information about a template-id annotation
|
||||
/// token, which contains the template declaration, template
|
||||
/// arguments, whether those template arguments were types or
|
||||
/// expressions, and the source locations for important tokens. All of
|
||||
/// the information about template arguments is allocated directly
|
||||
/// after this structure.
|
||||
struct TemplateIdAnnotation {
|
||||
/// TemplateNameLoc - The location of the template name within the
|
||||
/// source.
|
||||
SourceLocation TemplateNameLoc;
|
||||
|
||||
/// FIXME: Temporarily stores the name of a specialization
|
||||
IdentifierInfo *Name;
|
||||
|
||||
/// FIXME: Temporarily stores the overloaded operator kind.
|
||||
OverloadedOperatorKind Operator;
|
||||
|
||||
/// The declaration of the template corresponding to the
|
||||
/// template-name. This is an Action::DeclTy*.
|
||||
void *Template;
|
||||
|
||||
/// The kind of template that Template refers to.
|
||||
TemplateNameKind Kind;
|
||||
|
||||
/// The location of the '<' before the template argument
|
||||
/// list.
|
||||
SourceLocation LAngleLoc;
|
||||
|
||||
/// The location of the '>' after the template argument
|
||||
/// list.
|
||||
SourceLocation RAngleLoc;
|
||||
|
||||
/// NumArgs - The number of template arguments.
|
||||
unsigned NumArgs;
|
||||
|
||||
/// \brief Retrieves a pointer to the template arguments
|
||||
void **getTemplateArgs() { return (void **)(this + 1); }
|
||||
|
||||
/// \brief Retrieves a pointer to the array of template argument
|
||||
/// locations.
|
||||
SourceLocation *getTemplateArgLocations() {
|
||||
return (SourceLocation *)(getTemplateArgs() + NumArgs);
|
||||
}
|
||||
|
||||
/// \brief Retrieves a pointer to the array of flags that states
|
||||
/// whether the template arguments are types.
|
||||
bool *getTemplateArgIsType() {
|
||||
return (bool *)(getTemplateArgLocations() + NumArgs);
|
||||
}
|
||||
|
||||
static TemplateIdAnnotation* Allocate(unsigned NumArgs) {
|
||||
TemplateIdAnnotation *TemplateId
|
||||
= (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
|
||||
sizeof(void*) * NumArgs +
|
||||
sizeof(SourceLocation) * NumArgs +
|
||||
sizeof(bool) * NumArgs);
|
||||
TemplateId->NumArgs = NumArgs;
|
||||
return TemplateId;
|
||||
}
|
||||
|
||||
void Destroy() { free(this); }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1632,7 +1632,6 @@ public:
|
|||
SourceLocation TemplateLoc,
|
||||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgs,
|
||||
SourceLocation *TemplateArgLocs,
|
||||
SourceLocation RAngleLoc) {
|
||||
return TypeResult();
|
||||
};
|
||||
|
@ -1737,7 +1736,6 @@ public:
|
|||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgs,
|
||||
SourceLocation *TemplateArgLocs,
|
||||
SourceLocation RAngleLoc,
|
||||
AttributeList *Attr,
|
||||
MultiTemplateParamsArg TemplateParameterLists) {
|
||||
|
@ -1817,7 +1815,6 @@ public:
|
|||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgs,
|
||||
SourceLocation *TemplateArgLocs,
|
||||
SourceLocation RAngleLoc,
|
||||
AttributeList *Attr) {
|
||||
return DeclResult();
|
||||
|
|
|
@ -25,7 +25,8 @@ namespace clang {
|
|||
class IdentifierInfo;
|
||||
class Preprocessor;
|
||||
class Declarator;
|
||||
|
||||
struct TemplateIdAnnotation;
|
||||
|
||||
/// DeclSpec - This class captures information about "declaration specifiers",
|
||||
/// which encompasses storage-class-specifiers, type-specifiers,
|
||||
/// type-qualifiers, and function-specifiers.
|
||||
|
@ -642,13 +643,7 @@ public:
|
|||
/// \param TemplateId the template-id annotation that describes the parsed
|
||||
/// template-id. This UnqualifiedId instance will take ownership of the
|
||||
/// \p TemplateId and will free it on destruction.
|
||||
void setTemplateId(TemplateIdAnnotation *TemplateId) {
|
||||
assert(TemplateId && "NULL template-id annotation?");
|
||||
Kind = IK_TemplateId;
|
||||
this->TemplateId = TemplateId;
|
||||
StartLocation = TemplateId->TemplateNameLoc;
|
||||
EndLocation = TemplateId->RAngleLoc;
|
||||
}
|
||||
void setTemplateId(TemplateIdAnnotation *TemplateId);
|
||||
|
||||
/// \brief Return the source range that covers this unqualified-id.
|
||||
SourceRange getSourceRange() const {
|
||||
|
|
|
@ -654,41 +654,33 @@ namespace clang {
|
|||
#endif
|
||||
};
|
||||
|
||||
class ParsedTemplateArgument;
|
||||
|
||||
class ASTTemplateArgsPtr {
|
||||
#if !defined(DISABLE_SMART_POINTERS)
|
||||
ActionBase &Actions;
|
||||
#endif
|
||||
void **Args;
|
||||
bool *ArgIsType;
|
||||
ParsedTemplateArgument *Args;
|
||||
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;
|
||||
}
|
||||
void destroy();
|
||||
#endif
|
||||
|
||||
|
||||
public:
|
||||
ASTTemplateArgsPtr(ActionBase &actions, void **args, bool *argIsType,
|
||||
ASTTemplateArgsPtr(ActionBase &actions, ParsedTemplateArgument *args,
|
||||
unsigned count) :
|
||||
#if !defined(DISABLE_SMART_POINTERS)
|
||||
Actions(actions),
|
||||
#endif
|
||||
Args(args), ArgIsType(argIsType), Count(count) { }
|
||||
Args(args), 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) {
|
||||
Args(Other.Args), Count(Other.Count) {
|
||||
#if !defined(DISABLE_SMART_POINTERS)
|
||||
Other.Count = 0;
|
||||
#endif
|
||||
|
@ -700,7 +692,6 @@ namespace clang {
|
|||
Actions = Other.Actions;
|
||||
#endif
|
||||
Args = Other.Args;
|
||||
ArgIsType = Other.ArgIsType;
|
||||
Count = Other.Count;
|
||||
#if !defined(DISABLE_SMART_POINTERS)
|
||||
Other.Count = 0;
|
||||
|
@ -712,22 +703,20 @@ namespace clang {
|
|||
~ASTTemplateArgsPtr() { destroy(); }
|
||||
#endif
|
||||
|
||||
void **getArgs() const { return Args; }
|
||||
bool *getArgIsType() const {return ArgIsType; }
|
||||
ParsedTemplateArgument *getArgs() const { return Args; }
|
||||
unsigned size() const { return Count; }
|
||||
|
||||
void reset(void **args, bool *argIsType, unsigned count) {
|
||||
void reset(ParsedTemplateArgument *args, unsigned count) {
|
||||
#if !defined(DISABLE_SMART_POINTERS)
|
||||
destroy();
|
||||
#endif
|
||||
Args = args;
|
||||
ArgIsType = argIsType;
|
||||
Count = count;
|
||||
}
|
||||
|
||||
void *operator[](unsigned Arg) const { return Args[Arg]; }
|
||||
const ParsedTemplateArgument &operator[](unsigned Arg) const;
|
||||
|
||||
void **release() const {
|
||||
ParsedTemplateArgument *release() const {
|
||||
#if !defined(DISABLE_SMART_POINTERS)
|
||||
Count = 0;
|
||||
#endif
|
||||
|
|
|
@ -331,7 +331,7 @@ private:
|
|||
/// either "commit the consumed tokens" or revert to the previously marked
|
||||
/// token position. Example:
|
||||
///
|
||||
/// TentativeParsingAction TPA;
|
||||
/// TentativeParsingAction TPA(*this);
|
||||
/// ConsumeToken();
|
||||
/// ....
|
||||
/// TPA.Revert();
|
||||
|
@ -1347,9 +1347,7 @@ private:
|
|||
DeclPtrTy ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
|
||||
DeclPtrTy ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
|
||||
// C++ 14.3: Template arguments [temp.arg]
|
||||
typedef llvm::SmallVector<void *, 16> TemplateArgList;
|
||||
typedef llvm::SmallVector<bool, 16> TemplateArgIsTypeList;
|
||||
typedef llvm::SmallVector<SourceLocation, 16> TemplateArgLocationList;
|
||||
typedef llvm::SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
|
||||
|
||||
bool ParseTemplateIdAfterTemplateName(TemplateTy Template,
|
||||
SourceLocation TemplateNameLoc,
|
||||
|
@ -1357,8 +1355,6 @@ private:
|
|||
bool ConsumeLastToken,
|
||||
SourceLocation &LAngleLoc,
|
||||
TemplateArgList &TemplateArgs,
|
||||
TemplateArgIsTypeList &TemplateArgIsType,
|
||||
TemplateArgLocationList &TemplateArgLocations,
|
||||
SourceLocation &RAngleLoc);
|
||||
|
||||
bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
|
||||
|
@ -1367,10 +1363,8 @@ private:
|
|||
SourceLocation TemplateKWLoc = SourceLocation(),
|
||||
bool AllowTypeAnnotation = true);
|
||||
void AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS = 0);
|
||||
bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
|
||||
TemplateArgIsTypeList &TemplateArgIsType,
|
||||
TemplateArgLocationList &TemplateArgLocations);
|
||||
void *ParseTemplateArgument(bool &ArgIsType);
|
||||
bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
|
||||
ParsedTemplateArgument ParseTemplateArgument();
|
||||
DeclPtrTy ParseExplicitInstantiation(SourceLocation ExternLoc,
|
||||
SourceLocation TemplateLoc,
|
||||
SourceLocation &DeclEnd);
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
//===--- Template.h - Template Parsing Data Types -------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides data structures that store the parsed representation of
|
||||
// templates.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_CLANG_PARSE_TEMPLATE_H
|
||||
#define LLVM_CLANG_PARSE_TEMPLATE_H
|
||||
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
#include "clang/Parse/Ownership.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace clang {
|
||||
/// \brief Represents the parsed form of a C++ template argument.
|
||||
class ParsedTemplateArgument {
|
||||
public:
|
||||
/// \brief Describes the kind of template argument that was parsed.
|
||||
enum KindType {
|
||||
/// \brief A template type parameter, stored as a type.
|
||||
Type,
|
||||
/// \brief A non-type template parameter, stored as an expression.
|
||||
NonType,
|
||||
/// \brief A template template argument, stored as a template name.
|
||||
Template
|
||||
};
|
||||
|
||||
/// \brief Build an empty template argument. This template argument
|
||||
ParsedTemplateArgument() : Kind(Type), Arg(0) { }
|
||||
|
||||
/// \brief Create a template type argument or non-type template argument.
|
||||
///
|
||||
/// \param Arg the template type argument or non-type template argument.
|
||||
/// \param Loc the location of the type.
|
||||
ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
|
||||
: Kind(Kind), Arg(Arg), Loc(Loc) { }
|
||||
|
||||
/// \brief Create a template template argument.
|
||||
///
|
||||
/// \param SS the C++ scope specifier that precedes the template name, if
|
||||
/// any.
|
||||
///
|
||||
/// \param Template the template to which this template template
|
||||
/// argument refers.
|
||||
///
|
||||
/// \param TemplateLoc the location of the template name.
|
||||
ParsedTemplateArgument(const CXXScopeSpec &SS,
|
||||
ActionBase::TemplateTy Template,
|
||||
SourceLocation TemplateLoc)
|
||||
: Kind(ParsedTemplateArgument::Template), Arg(Template.get()),
|
||||
Loc(TemplateLoc), SS(SS) { }
|
||||
|
||||
/// \brief Determine whether the given template argument is invalid.
|
||||
bool isInvalid() { return Arg == 0; }
|
||||
|
||||
/// \brief Determine what kind of template argument we have.
|
||||
KindType getKind() const { return Kind; }
|
||||
|
||||
/// \brief Retrieve the template type argument's type.
|
||||
ActionBase::TypeTy *getAsType() const {
|
||||
assert(Kind == Type && "Not a template type argument");
|
||||
return Arg;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the non-type template argument's expression.
|
||||
ActionBase::ExprTy *getAsExpr() const {
|
||||
assert(Kind == NonType && "Not a non-type template argument");
|
||||
return Arg;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the template template argument's template name.
|
||||
ActionBase::TemplateTy getAsTemplate() const {
|
||||
assert(Kind == Template && "Not a template template argument");
|
||||
return ActionBase::TemplateTy::make(Arg);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the location of the template argument.
|
||||
SourceLocation getLocation() const { return Loc; }
|
||||
|
||||
/// \brief Retrieve the nested-name-specifier that precedes the template
|
||||
/// name in a template template argument.
|
||||
const CXXScopeSpec &getScopeSpec() const {
|
||||
assert(Kind == Template &&
|
||||
"Only template template arguments can have a scope specifier");
|
||||
return SS;
|
||||
}
|
||||
|
||||
private:
|
||||
KindType Kind;
|
||||
|
||||
/// \brief The actual template argument representation, which may be
|
||||
/// an \c ActionBase::TypeTy* (for a type), an ActionBase::ExprTy* (for an
|
||||
/// expression), or an ActionBase::TemplateTy (for a template).
|
||||
void *Arg;
|
||||
|
||||
/// \brief the location of the template argument.
|
||||
SourceLocation Loc;
|
||||
|
||||
/// \brief The nested-name-specifier that can accompany a template template
|
||||
/// argument.
|
||||
CXXScopeSpec SS;
|
||||
};
|
||||
|
||||
/// \brief Information about a template-id annotation
|
||||
/// token.
|
||||
///
|
||||
/// A template-id annotation token contains the template declaration,
|
||||
/// template arguments, whether those template arguments were types,
|
||||
/// expressions, or template names, and the source locations for important
|
||||
/// tokens. All of the information about template arguments is allocated
|
||||
/// directly after this structure.
|
||||
struct TemplateIdAnnotation {
|
||||
/// TemplateNameLoc - The location of the template name within the
|
||||
/// source.
|
||||
SourceLocation TemplateNameLoc;
|
||||
|
||||
/// FIXME: Temporarily stores the name of a specialization
|
||||
IdentifierInfo *Name;
|
||||
|
||||
/// FIXME: Temporarily stores the overloaded operator kind.
|
||||
OverloadedOperatorKind Operator;
|
||||
|
||||
/// The declaration of the template corresponding to the
|
||||
/// template-name. This is an Action::TemplateTy.
|
||||
void *Template;
|
||||
|
||||
/// The kind of template that Template refers to.
|
||||
TemplateNameKind Kind;
|
||||
|
||||
/// The location of the '<' before the template argument
|
||||
/// list.
|
||||
SourceLocation LAngleLoc;
|
||||
|
||||
/// The location of the '>' after the template argument
|
||||
/// list.
|
||||
SourceLocation RAngleLoc;
|
||||
|
||||
/// NumArgs - The number of template arguments.
|
||||
unsigned NumArgs;
|
||||
|
||||
/// \brief Retrieves a pointer to the template arguments
|
||||
ParsedTemplateArgument *getTemplateArgs() {
|
||||
return reinterpret_cast<ParsedTemplateArgument *>(this + 1);
|
||||
}
|
||||
|
||||
static TemplateIdAnnotation* Allocate(unsigned NumArgs) {
|
||||
TemplateIdAnnotation *TemplateId
|
||||
= (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
|
||||
sizeof(ParsedTemplateArgument) * NumArgs);
|
||||
TemplateId->NumArgs = NumArgs;
|
||||
return TemplateId;
|
||||
}
|
||||
|
||||
void Destroy() { free(this); }
|
||||
};
|
||||
|
||||
#if !defined(DISABLE_SMART_POINTERS)
|
||||
inline void ASTTemplateArgsPtr::destroy() {
|
||||
if (!Count)
|
||||
return;
|
||||
|
||||
for (unsigned I = 0; I != Count; ++I)
|
||||
if (Args[I].getKind() == ParsedTemplateArgument::NonType)
|
||||
Actions.DeleteExpr(Args[I].getAsExpr());
|
||||
|
||||
Count = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline const ParsedTemplateArgument &
|
||||
ASTTemplateArgsPtr::operator[](unsigned Arg) const {
|
||||
return Args[Arg];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Parse/Template.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
@ -26,6 +27,15 @@ static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc,
|
|||
return D.Report(FullSourceLoc(Loc, SrcMgr), DiagID);
|
||||
}
|
||||
|
||||
|
||||
void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
|
||||
assert(TemplateId && "NULL template-id annotation?");
|
||||
Kind = IK_TemplateId;
|
||||
this->TemplateId = TemplateId;
|
||||
StartLocation = TemplateId->TemplateNameLoc;
|
||||
EndLocation = TemplateId->RAngleLoc;
|
||||
}
|
||||
|
||||
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
|
||||
/// "TheDeclarator" is the declarator that this will be added to.
|
||||
DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "clang/Parse/Parser.h"
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Parse/Scope.h"
|
||||
#include "clang/Parse/Template.h"
|
||||
#include "ExtensionRAIIObject.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
using namespace clang;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
#include "clang/Parse/Scope.h"
|
||||
#include "clang/Parse/Template.h"
|
||||
#include "ExtensionRAIIObject.h"
|
||||
using namespace clang;
|
||||
|
||||
|
@ -586,13 +587,10 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
|||
// Eat the template argument list and try to continue parsing this as
|
||||
// a class (or template thereof).
|
||||
TemplateArgList TemplateArgs;
|
||||
TemplateArgIsTypeList TemplateArgIsType;
|
||||
TemplateArgLocationList TemplateArgLocations;
|
||||
SourceLocation LAngleLoc, RAngleLoc;
|
||||
if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, &SS,
|
||||
true, LAngleLoc,
|
||||
TemplateArgs, TemplateArgIsType,
|
||||
TemplateArgLocations, RAngleLoc)) {
|
||||
TemplateArgs, RAngleLoc)) {
|
||||
// We couldn't parse the template argument list at all, so don't
|
||||
// try to give any location information for the list.
|
||||
LAngleLoc = RAngleLoc = SourceLocation();
|
||||
|
@ -704,7 +702,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
|||
// or explicit instantiation.
|
||||
ASTTemplateArgsPtr TemplateArgsPtr(Actions,
|
||||
TemplateId->getTemplateArgs(),
|
||||
TemplateId->getTemplateArgIsType(),
|
||||
TemplateId->NumArgs);
|
||||
if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
|
||||
TUK == Action::TUK_Declaration) {
|
||||
|
@ -720,7 +717,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
|||
TemplateId->TemplateNameLoc,
|
||||
TemplateId->LAngleLoc,
|
||||
TemplateArgsPtr,
|
||||
TemplateId->getTemplateArgLocations(),
|
||||
TemplateId->RAngleLoc,
|
||||
Attr);
|
||||
} else if (TUK == Action::TUK_Reference) {
|
||||
|
@ -729,7 +725,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
|||
TemplateId->TemplateNameLoc,
|
||||
TemplateId->LAngleLoc,
|
||||
TemplateArgsPtr,
|
||||
TemplateId->getTemplateArgLocations(),
|
||||
TemplateId->RAngleLoc);
|
||||
|
||||
TypeResult = Actions.ActOnTagTemplateIdType(TypeResult, TUK,
|
||||
|
@ -777,7 +772,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
|||
TemplateId->TemplateNameLoc,
|
||||
TemplateId->LAngleLoc,
|
||||
TemplateArgsPtr,
|
||||
TemplateId->getTemplateArgLocations(),
|
||||
TemplateId->RAngleLoc,
|
||||
Attr,
|
||||
Action::MultiTemplateParamsArg(Actions,
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Parse/Parser.h"
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
#include "clang/Parse/Template.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
using namespace clang;
|
||||
|
@ -814,13 +815,9 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
|
|||
// Parse the enclosed template argument list.
|
||||
SourceLocation LAngleLoc, RAngleLoc;
|
||||
TemplateArgList TemplateArgs;
|
||||
TemplateArgIsTypeList TemplateArgIsType;
|
||||
TemplateArgLocationList TemplateArgLocations;
|
||||
if (ParseTemplateIdAfterTemplateName(Template, Id.StartLocation,
|
||||
&SS, true, LAngleLoc,
|
||||
TemplateArgs,
|
||||
TemplateArgIsType,
|
||||
TemplateArgLocations,
|
||||
RAngleLoc))
|
||||
return true;
|
||||
|
||||
|
@ -845,15 +842,10 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
|
|||
TemplateId->Kind = TNK;
|
||||
TemplateId->LAngleLoc = LAngleLoc;
|
||||
TemplateId->RAngleLoc = RAngleLoc;
|
||||
void **Args = TemplateId->getTemplateArgs();
|
||||
bool *ArgIsType = TemplateId->getTemplateArgIsType();
|
||||
SourceLocation *ArgLocs = TemplateId->getTemplateArgLocations();
|
||||
ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
|
||||
for (unsigned Arg = 0, ArgEnd = TemplateArgs.size();
|
||||
Arg != ArgEnd; ++Arg) {
|
||||
Arg != ArgEnd; ++Arg)
|
||||
Args[Arg] = TemplateArgs[Arg];
|
||||
ArgIsType[Arg] = TemplateArgIsType[Arg];
|
||||
ArgLocs[Arg] = TemplateArgLocations[Arg];
|
||||
}
|
||||
|
||||
Id.setTemplateId(TemplateId);
|
||||
return false;
|
||||
|
@ -861,14 +853,12 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
|
|||
|
||||
// Bundle the template arguments together.
|
||||
ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(),
|
||||
TemplateArgIsType.data(),
|
||||
TemplateArgs.size());
|
||||
|
||||
// Constructor and destructor names.
|
||||
Action::TypeResult Type
|
||||
= Actions.ActOnTemplateIdType(Template, NameLoc,
|
||||
LAngleLoc, TemplateArgsPtr,
|
||||
&TemplateArgLocations[0],
|
||||
RAngleLoc);
|
||||
if (Type.isInvalid())
|
||||
return true;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
#include "clang/Parse/Scope.h"
|
||||
#include "clang/Parse/Template.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
using namespace clang;
|
||||
|
||||
|
@ -582,8 +583,6 @@ Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template,
|
|||
bool ConsumeLastToken,
|
||||
SourceLocation &LAngleLoc,
|
||||
TemplateArgList &TemplateArgs,
|
||||
TemplateArgIsTypeList &TemplateArgIsType,
|
||||
TemplateArgLocationList &TemplateArgLocations,
|
||||
SourceLocation &RAngleLoc) {
|
||||
assert(Tok.is(tok::less) && "Must have already parsed the template-name");
|
||||
|
||||
|
@ -595,8 +594,7 @@ Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template,
|
|||
{
|
||||
GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
|
||||
if (Tok.isNot(tok::greater))
|
||||
Invalid = ParseTemplateArgumentList(TemplateArgs, TemplateArgIsType,
|
||||
TemplateArgLocations);
|
||||
Invalid = ParseTemplateArgumentList(TemplateArgs);
|
||||
|
||||
if (Invalid) {
|
||||
// Try to find the closing '>'.
|
||||
|
@ -688,14 +686,10 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
|
|||
// Parse the enclosed template argument list.
|
||||
SourceLocation LAngleLoc, RAngleLoc;
|
||||
TemplateArgList TemplateArgs;
|
||||
TemplateArgIsTypeList TemplateArgIsType;
|
||||
TemplateArgLocationList TemplateArgLocations;
|
||||
bool Invalid = ParseTemplateIdAfterTemplateName(Template,
|
||||
TemplateNameLoc,
|
||||
SS, false, LAngleLoc,
|
||||
TemplateArgs,
|
||||
TemplateArgIsType,
|
||||
TemplateArgLocations,
|
||||
RAngleLoc);
|
||||
|
||||
if (Invalid) {
|
||||
|
@ -707,7 +701,6 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
|
|||
}
|
||||
|
||||
ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(),
|
||||
TemplateArgIsType.data(),
|
||||
TemplateArgs.size());
|
||||
|
||||
// Build the annotation token.
|
||||
|
@ -715,7 +708,6 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
|
|||
Action::TypeResult Type
|
||||
= Actions.ActOnTemplateIdType(Template, TemplateNameLoc,
|
||||
LAngleLoc, TemplateArgsPtr,
|
||||
&TemplateArgLocations[0],
|
||||
RAngleLoc);
|
||||
if (Type.isInvalid()) {
|
||||
// If we failed to parse the template ID but skipped ahead to a >, we're not
|
||||
|
@ -751,14 +743,9 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
|
|||
TemplateId->Kind = TNK;
|
||||
TemplateId->LAngleLoc = LAngleLoc;
|
||||
TemplateId->RAngleLoc = RAngleLoc;
|
||||
void **Args = TemplateId->getTemplateArgs();
|
||||
bool *ArgIsType = TemplateId->getTemplateArgIsType();
|
||||
SourceLocation *ArgLocs = TemplateId->getTemplateArgLocations();
|
||||
for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg) {
|
||||
ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
|
||||
for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg)
|
||||
Args[Arg] = TemplateArgs[Arg];
|
||||
ArgIsType[Arg] = TemplateArgIsType[Arg];
|
||||
ArgLocs[Arg] = TemplateArgLocations[Arg];
|
||||
}
|
||||
Tok.setAnnotationValue(TemplateId);
|
||||
if (TemplateKWLoc.isValid())
|
||||
Tok.setLocation(TemplateKWLoc);
|
||||
|
@ -794,7 +781,6 @@ void Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) {
|
|||
|
||||
ASTTemplateArgsPtr TemplateArgsPtr(Actions,
|
||||
TemplateId->getTemplateArgs(),
|
||||
TemplateId->getTemplateArgIsType(),
|
||||
TemplateId->NumArgs);
|
||||
|
||||
Action::TypeResult Type
|
||||
|
@ -802,7 +788,6 @@ void Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) {
|
|||
TemplateId->TemplateNameLoc,
|
||||
TemplateId->LAngleLoc,
|
||||
TemplateArgsPtr,
|
||||
TemplateId->getTemplateArgLocations(),
|
||||
TemplateId->RAngleLoc);
|
||||
// Create the new "type" annotation token.
|
||||
Tok.setKind(tok::annot_typename);
|
||||
|
@ -817,33 +802,112 @@ void Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) {
|
|||
TemplateId->Destroy();
|
||||
}
|
||||
|
||||
/// \brief Determine whether the given token can end a template argument.
|
||||
static const bool isEndOfTemplateArgument(Token Tok) {
|
||||
return Tok.is(tok::comma) || Tok.is(tok::greater) ||
|
||||
Tok.is(tok::greatergreater);
|
||||
}
|
||||
|
||||
/// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
|
||||
///
|
||||
/// template-argument: [C++ 14.2]
|
||||
/// constant-expression
|
||||
/// type-id
|
||||
/// id-expression
|
||||
void *Parser::ParseTemplateArgument(bool &ArgIsType) {
|
||||
ParsedTemplateArgument Parser::ParseTemplateArgument() {
|
||||
// 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
|
||||
// the corresponding template-parameter.
|
||||
//
|
||||
// Therefore, we initially try to parse a type-id.
|
||||
// Therefore, we initially try to parse a type-id.
|
||||
if (isCXXTypeId(TypeIdAsTemplateArgument)) {
|
||||
ArgIsType = true;
|
||||
SourceLocation Loc = Tok.getLocation();
|
||||
TypeResult TypeArg = ParseTypeName();
|
||||
if (TypeArg.isInvalid())
|
||||
return 0;
|
||||
return TypeArg.get();
|
||||
return ParsedTemplateArgument();
|
||||
|
||||
return ParsedTemplateArgument(ParsedTemplateArgument::Type, TypeArg.get(),
|
||||
Loc);
|
||||
}
|
||||
|
||||
// C++0x [temp.arg.template]p1:
|
||||
// A template-argument for a template template-parameter shall be the name
|
||||
// of a class template or a template alias, expressed as id-expression.
|
||||
//
|
||||
// We perform some tentative parsing at this point, to determine whether
|
||||
// we have an id-expression that refers to a class template or template
|
||||
// alias. The grammar we tentatively parse is:
|
||||
//
|
||||
// nested-name-specifier[opt] template[opt] identifier
|
||||
//
|
||||
// followed by a token that terminates a template argument, such as ',',
|
||||
// '>', or (in some cases) '>>'.
|
||||
if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
|
||||
Tok.is(tok::annot_cxxscope)) {
|
||||
TentativeParsingAction TPA(*this);
|
||||
CXXScopeSpec SS; // nested-name-specifier, if present
|
||||
ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0,
|
||||
/*EnteringContext=*/false);
|
||||
|
||||
if (SS.isSet() && Tok.is(tok::kw_template)) {
|
||||
// Parse the optional 'template' keyword following the
|
||||
// nested-name-specifier.
|
||||
SourceLocation TemplateLoc = ConsumeToken();
|
||||
|
||||
if (Tok.is(tok::identifier)) {
|
||||
// We appear to have a dependent template name.
|
||||
UnqualifiedId Name;
|
||||
Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
|
||||
ConsumeToken(); // the identifier
|
||||
|
||||
// If the next token signals the end of a template argument,
|
||||
// then we have a dependent template name that could be a template
|
||||
// template argument.
|
||||
if (isEndOfTemplateArgument(Tok)) {
|
||||
TemplateTy Template
|
||||
= Actions.ActOnDependentTemplateName(TemplateLoc, SS, Name,
|
||||
/*ObjectType=*/0);
|
||||
if (Template.get()) {
|
||||
TPA.Commit();
|
||||
return ParsedTemplateArgument(SS, Template, Name.StartLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (Tok.is(tok::identifier)) {
|
||||
// We may have a (non-dependent) template name.
|
||||
TemplateTy Template;
|
||||
UnqualifiedId Name;
|
||||
Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
|
||||
ConsumeToken(); // the identifier
|
||||
|
||||
if (isEndOfTemplateArgument(Tok)) {
|
||||
TemplateNameKind TNK = Actions.isTemplateName(CurScope, SS, Name,
|
||||
/*ObjectType=*/0,
|
||||
/*EnteringContext=*/false,
|
||||
Template);
|
||||
if (TNK == TNK_Dependent_template_name || TNK == TNK_Type_template) {
|
||||
// We have an id-expression that refers to a class template or
|
||||
// (C++0x) template alias.
|
||||
TPA.Commit();
|
||||
return ParsedTemplateArgument(SS, Template, Name.StartLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We don't have a template template argument; revert everything we have
|
||||
// tentatively parsed.
|
||||
TPA.Revert();
|
||||
}
|
||||
|
||||
// Parse a non-type template argument.
|
||||
SourceLocation Loc = Tok.getLocation();
|
||||
OwningExprResult ExprArg = ParseConstantExpression();
|
||||
if (ExprArg.isInvalid() || !ExprArg.get())
|
||||
return 0;
|
||||
return ParsedTemplateArgument();
|
||||
|
||||
ArgIsType = false;
|
||||
return ExprArg.release();
|
||||
return ParsedTemplateArgument(ParsedTemplateArgument::NonType,
|
||||
ExprArg.release(), Loc);
|
||||
}
|
||||
|
||||
/// ParseTemplateArgumentList - Parse a C++ template-argument-list
|
||||
|
@ -853,22 +917,17 @@ void *Parser::ParseTemplateArgument(bool &ArgIsType) {
|
|||
/// template-argument
|
||||
/// template-argument-list ',' template-argument
|
||||
bool
|
||||
Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
|
||||
TemplateArgIsTypeList &TemplateArgIsType,
|
||||
TemplateArgLocationList &TemplateArgLocations) {
|
||||
Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
|
||||
while (true) {
|
||||
bool IsType = false;
|
||||
SourceLocation Loc = Tok.getLocation();
|
||||
void *Arg = ParseTemplateArgument(IsType);
|
||||
if (Arg) {
|
||||
TemplateArgs.push_back(Arg);
|
||||
TemplateArgIsType.push_back(IsType);
|
||||
TemplateArgLocations.push_back(Loc);
|
||||
} else {
|
||||
ParsedTemplateArgument Arg = ParseTemplateArgument();
|
||||
if (Arg.isInvalid()) {
|
||||
SkipUntil(tok::comma, tok::greater, true, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Save this template argument.
|
||||
TemplateArgs.push_back(Arg);
|
||||
|
||||
// If the next token is a comma, consume it and keep reading
|
||||
// arguments.
|
||||
if (Tok.isNot(tok::comma)) break;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
#include "clang/Parse/Scope.h"
|
||||
#include "clang/Parse/Template.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "ExtensionRAIIObject.h"
|
||||
#include "ParsePragma.h"
|
||||
|
|
|
@ -2472,8 +2472,7 @@ public:
|
|||
AccessSpecifier AS);
|
||||
|
||||
void translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
|
||||
SourceLocation *TemplateArgLocsIn,
|
||||
llvm::SmallVector<TemplateArgumentLoc, 16> &TempArgs);
|
||||
llvm::SmallVectorImpl<TemplateArgumentLoc> &TempArgs);
|
||||
|
||||
QualType CheckTemplateIdType(TemplateName Template,
|
||||
SourceLocation TemplateLoc,
|
||||
|
@ -2486,7 +2485,6 @@ public:
|
|||
ActOnTemplateIdType(TemplateTy Template, SourceLocation TemplateLoc,
|
||||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgs,
|
||||
SourceLocation *TemplateArgLocs,
|
||||
SourceLocation RAngleLoc);
|
||||
|
||||
virtual TypeResult ActOnTagTemplateIdType(TypeResult Type,
|
||||
|
@ -2508,7 +2506,6 @@ public:
|
|||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgs,
|
||||
SourceLocation *TemplateArgLocs,
|
||||
SourceLocation RAngleLoc);
|
||||
|
||||
virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
|
||||
|
@ -2529,7 +2526,6 @@ public:
|
|||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgs,
|
||||
SourceLocation *TemplateArgLocs,
|
||||
SourceLocation RAngleLoc,
|
||||
AttributeList *Attr,
|
||||
MultiTemplateParamsArg TemplateParameterLists);
|
||||
|
@ -2570,7 +2566,6 @@ public:
|
|||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgs,
|
||||
SourceLocation *TemplateArgLocs,
|
||||
SourceLocation RAngleLoc,
|
||||
AttributeList *Attr);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "clang/AST/StmtObjC.h"
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
#include "clang/Parse/ParseDiagnostic.h"
|
||||
#include "clang/Parse/Template.h"
|
||||
#include "clang/Basic/PartialDiagnostic.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
|
@ -1669,7 +1670,7 @@ DeclarationName Sema::GetNameFromUnqualifiedId(UnqualifiedId &Name) {
|
|||
|
||||
case UnqualifiedId::IK_TemplateId: {
|
||||
TemplateName TName
|
||||
= TemplateName::getFromVoidPointer(Name.TemplateId->Template);
|
||||
= TemplateName::getFromVoidPointer(Name.TemplateId->Template);
|
||||
if (TemplateDecl *Template = TName.getAsTemplateDecl())
|
||||
return Template->getDeclName();
|
||||
if (OverloadedFunctionDecl *Ovl = TName.getAsOverloadedFunctionDecl())
|
||||
|
@ -2835,10 +2836,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
|||
TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
|
||||
ASTTemplateArgsPtr TemplateArgsPtr(*this,
|
||||
TemplateId->getTemplateArgs(),
|
||||
TemplateId->getTemplateArgIsType(),
|
||||
TemplateId->NumArgs);
|
||||
translateTemplateArguments(TemplateArgsPtr,
|
||||
TemplateId->getTemplateArgLocations(),
|
||||
TemplateArgs);
|
||||
TemplateArgsPtr.release();
|
||||
|
||||
|
|
|
@ -18,9 +18,10 @@
|
|||
#include "clang/AST/DeclVisitor.h"
|
||||
#include "clang/AST/TypeOrdering.h"
|
||||
#include "clang/AST/StmtVisitor.h"
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
#include "clang/Parse/Template.h"
|
||||
#include "clang/Basic/PartialDiagnostic.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <algorithm> // for std::equal
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "clang/Parse/DeclSpec.h"
|
||||
#include "clang/Parse/Designator.h"
|
||||
#include "clang/Parse/Scope.h"
|
||||
#include "clang/Parse/Template.h"
|
||||
using namespace clang;
|
||||
|
||||
|
||||
|
@ -622,14 +623,12 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
|
|||
if (Name.getKind() == UnqualifiedId::IK_TemplateId) {
|
||||
ASTTemplateArgsPtr TemplateArgsPtr(*this,
|
||||
Name.TemplateId->getTemplateArgs(),
|
||||
Name.TemplateId->getTemplateArgIsType(),
|
||||
Name.TemplateId->NumArgs);
|
||||
return ActOnTemplateIdExpr(SS,
|
||||
TemplateTy::make(Name.TemplateId->Template),
|
||||
Name.TemplateId->TemplateNameLoc,
|
||||
Name.TemplateId->LAngleLoc,
|
||||
TemplateArgsPtr,
|
||||
Name.TemplateId->getTemplateArgLocations(),
|
||||
Name.TemplateId->RAngleLoc);
|
||||
}
|
||||
|
||||
|
@ -2501,12 +2500,10 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg Base,
|
|||
// Translate the parser's template argument list in our AST format.
|
||||
ASTTemplateArgsPtr TemplateArgsPtr(*this,
|
||||
Member.TemplateId->getTemplateArgs(),
|
||||
Member.TemplateId->getTemplateArgIsType(),
|
||||
Member.TemplateId->NumArgs);
|
||||
|
||||
llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
|
||||
translateTemplateArguments(TemplateArgsPtr,
|
||||
Member.TemplateId->getTemplateArgLocations(),
|
||||
TemplateArgs);
|
||||
TemplateArgsPtr.release();
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/Parse/DeclSpec.h"
|
||||
#include "clang/Parse/Template.h"
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
#include "clang/Basic/PartialDiagnostic.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
@ -1121,21 +1122,43 @@ Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
|
|||
/// \brief Translates template arguments as provided by the parser
|
||||
/// into template arguments used by semantic analysis.
|
||||
void Sema::translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
|
||||
SourceLocation *TemplateArgLocs,
|
||||
llvm::SmallVector<TemplateArgumentLoc, 16> &TemplateArgs) {
|
||||
llvm::SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) {
|
||||
TemplateArgs.reserve(TemplateArgsIn.size());
|
||||
|
||||
void **Args = TemplateArgsIn.getArgs();
|
||||
bool *ArgIsType = TemplateArgsIn.getArgIsType();
|
||||
for (unsigned Arg = 0, Last = TemplateArgsIn.size(); Arg != Last; ++Arg) {
|
||||
if (ArgIsType[Arg]) {
|
||||
for (unsigned I = 0, Last = TemplateArgsIn.size(); I != Last; ++I) {
|
||||
const ParsedTemplateArgument &Arg = TemplateArgsIn[I];
|
||||
switch (Arg.getKind()) {
|
||||
case ParsedTemplateArgument::Type: {
|
||||
DeclaratorInfo *DI;
|
||||
QualType T = Sema::GetTypeFromParser(Args[Arg], &DI);
|
||||
if (!DI) DI = Context.getTrivialDeclaratorInfo(T, TemplateArgLocs[Arg]);
|
||||
QualType T = Sema::GetTypeFromParser(Arg.getAsType(), &DI);
|
||||
if (!DI) DI = Context.getTrivialDeclaratorInfo(T, Arg.getLocation());
|
||||
TemplateArgs.push_back(TemplateArgumentLoc(TemplateArgument(T), DI));
|
||||
} else {
|
||||
Expr *E = reinterpret_cast<Expr *>(Args[Arg]);
|
||||
break;
|
||||
}
|
||||
|
||||
case ParsedTemplateArgument::NonType: {
|
||||
Expr *E = static_cast<Expr *>(Arg.getAsExpr());
|
||||
TemplateArgs.push_back(TemplateArgumentLoc(TemplateArgument(E), E));
|
||||
break;
|
||||
}
|
||||
|
||||
case ParsedTemplateArgument::Template: {
|
||||
TemplateName Template
|
||||
= TemplateName::getFromVoidPointer(Arg.getAsTemplate().get());
|
||||
|
||||
// FIXME: This is an egregious hack. We turn a nicely-parsed template name
|
||||
// into a DeclRefExpr, because that's how we previously parsed template
|
||||
// template parameters. This will disappear as part of the upcoming
|
||||
// implementation of template template parameters.
|
||||
const CXXScopeSpec &SS = Arg.getScopeSpec();
|
||||
Expr *E = DeclRefExpr::Create(Context,
|
||||
(NestedNameSpecifier *)SS.getScopeRep(),
|
||||
SS.getRange(),
|
||||
Template.getAsTemplateDecl(),
|
||||
Arg.getLocation(),
|
||||
Context.DependentTy, false, false);
|
||||
TemplateArgs.push_back(TemplateArgumentLoc(TemplateArgument(E), E));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1228,13 +1251,12 @@ Action::TypeResult
|
|||
Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
|
||||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgsIn,
|
||||
SourceLocation *TemplateArgLocsIn,
|
||||
SourceLocation RAngleLoc) {
|
||||
TemplateName Template = TemplateD.getAsVal<TemplateName>();
|
||||
|
||||
// Translate the parser's template argument list in our AST format.
|
||||
llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
|
||||
translateTemplateArguments(TemplateArgsIn, TemplateArgLocsIn, TemplateArgs);
|
||||
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
|
||||
|
||||
QualType Result = CheckTemplateIdType(Template, TemplateLoc, LAngleLoc,
|
||||
TemplateArgs.data(),
|
||||
|
@ -1336,13 +1358,12 @@ Sema::OwningExprResult Sema::ActOnTemplateIdExpr(const CXXScopeSpec &SS,
|
|||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgsIn,
|
||||
SourceLocation *TemplateArgSLs,
|
||||
SourceLocation RAngleLoc) {
|
||||
TemplateName Template = TemplateD.getAsVal<TemplateName>();
|
||||
|
||||
// Translate the parser's template argument list in our AST format.
|
||||
llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
|
||||
translateTemplateArguments(TemplateArgsIn, TemplateArgSLs, TemplateArgs);
|
||||
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
|
||||
TemplateArgsIn.release();
|
||||
|
||||
return BuildTemplateIdExpr((NestedNameSpecifier *)SS.getScopeRep(),
|
||||
|
@ -2803,7 +2824,6 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
|
|||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgsIn,
|
||||
SourceLocation *TemplateArgLocs,
|
||||
SourceLocation RAngleLoc,
|
||||
AttributeList *Attr,
|
||||
MultiTemplateParamsArg TemplateParameterLists) {
|
||||
|
@ -2898,7 +2918,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
|
|||
|
||||
// Translate the parser's template argument list in our AST format.
|
||||
llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
|
||||
translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
|
||||
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
|
||||
|
||||
// Check that the template argument list is well-formed for this
|
||||
// template.
|
||||
|
@ -3704,7 +3724,6 @@ Sema::ActOnExplicitInstantiation(Scope *S,
|
|||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgsIn,
|
||||
SourceLocation *TemplateArgLocs,
|
||||
SourceLocation RAngleLoc,
|
||||
AttributeList *Attr) {
|
||||
// Find the class template we're specializing
|
||||
|
@ -3743,7 +3762,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
|
|||
|
||||
// Translate the parser's template argument list in our AST format.
|
||||
llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
|
||||
translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
|
||||
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
|
||||
|
||||
// Check that the template argument list is well-formed for this
|
||||
// template.
|
||||
|
@ -4126,10 +4145,8 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
|
|||
TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
|
||||
ASTTemplateArgsPtr TemplateArgsPtr(*this,
|
||||
TemplateId->getTemplateArgs(),
|
||||
TemplateId->getTemplateArgIsType(),
|
||||
TemplateId->NumArgs);
|
||||
translateTemplateArguments(TemplateArgsPtr,
|
||||
TemplateId->getTemplateArgLocations(),
|
||||
TemplateArgs);
|
||||
HasExplicitTemplateArgs = true;
|
||||
TemplateArgsPtr.release();
|
||||
|
|
Loading…
Reference in New Issue