forked from OSchip/llvm-project
[NFC, Refactor] Modernize TemplateIdAnnotation using TrailingObjects
A refactoring of TemplateIdAnnotation that uses TrailingObjects to create a variably-sized object on the heap. https://reviews.llvm.org/D31414 Thanks to Aaron B for the review! llvm-svn: 303594
This commit is contained in:
parent
acf4b09fee
commit
43caf6785f
|
@ -26,13 +26,21 @@ enum TemplateNameKind {
|
|||
TNK_Function_template,
|
||||
/// The name refers to a template whose specialization produces a
|
||||
/// type. The template itself could be a class template, template
|
||||
/// template parameter, or C++0x template alias.
|
||||
/// template parameter, or template alias.
|
||||
TNK_Type_template,
|
||||
/// The name refers to a variable template whose specialization produces a
|
||||
/// variable.
|
||||
TNK_Var_template,
|
||||
/// The name refers to a dependent template name. Whether the
|
||||
/// template name is assumed to refer to a type template or a
|
||||
/// The name refers to a dependent template name:
|
||||
/// \code
|
||||
/// template<typename MetaFun, typename T1, typename T2> struct apply2 {
|
||||
/// typedef typename MetaFun::template apply<T1, T2>::type type;
|
||||
/// };
|
||||
/// \endcode
|
||||
///
|
||||
/// Here, "apply" is a dependent template name within the typename
|
||||
/// specifier in the typedef. "apply" is a nested template, and
|
||||
/// whether the template name is assumed to refer to a type template or a
|
||||
/// function template depends on the context in which the template
|
||||
/// name occurs.
|
||||
TNK_Dependent_template_name
|
||||
|
|
|
@ -145,12 +145,15 @@ namespace clang {
|
|||
/// 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 {
|
||||
struct TemplateIdAnnotation final
|
||||
: private llvm::TrailingObjects<TemplateIdAnnotation,
|
||||
ParsedTemplateArgument> {
|
||||
friend TrailingObjects;
|
||||
/// \brief The nested-name-specifier that precedes the template name.
|
||||
CXXScopeSpec SS;
|
||||
|
||||
/// TemplateKWLoc - The location of the template keyword within the
|
||||
/// source.
|
||||
/// TemplateKWLoc - The location of the template keyword.
|
||||
/// For e.g. typename T::template Y<U>
|
||||
SourceLocation TemplateKWLoc;
|
||||
|
||||
/// TemplateNameLoc - The location of the template name within the
|
||||
|
@ -183,34 +186,56 @@ namespace clang {
|
|||
|
||||
/// \brief Retrieves a pointer to the template arguments
|
||||
ParsedTemplateArgument *getTemplateArgs() {
|
||||
return reinterpret_cast<ParsedTemplateArgument *>(this + 1);
|
||||
return getTrailingObjects<ParsedTemplateArgument>();
|
||||
}
|
||||
|
||||
/// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
|
||||
/// appends it to List.
|
||||
static TemplateIdAnnotation *
|
||||
Allocate(unsigned NumArgs, SmallVectorImpl<TemplateIdAnnotation*> &List) {
|
||||
TemplateIdAnnotation *TemplateId
|
||||
= (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
|
||||
sizeof(ParsedTemplateArgument) * NumArgs);
|
||||
TemplateId->NumArgs = NumArgs;
|
||||
|
||||
// Default-construct nested-name-specifier.
|
||||
new (&TemplateId->SS) CXXScopeSpec();
|
||||
|
||||
// Default-construct parsed template arguments.
|
||||
ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs();
|
||||
for (unsigned I = 0; I != NumArgs; ++I)
|
||||
new (TemplateArgs + I) ParsedTemplateArgument();
|
||||
|
||||
List.push_back(TemplateId);
|
||||
Create(CXXScopeSpec SS, SourceLocation TemplateKWLoc,
|
||||
SourceLocation TemplateNameLoc, IdentifierInfo *Name,
|
||||
OverloadedOperatorKind OperatorKind,
|
||||
ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
|
||||
SourceLocation LAngleLoc, SourceLocation RAngleLoc,
|
||||
ArrayRef<ParsedTemplateArgument> TemplateArgs,
|
||||
SmallVectorImpl<TemplateIdAnnotation *> &CleanupList) {
|
||||
|
||||
TemplateIdAnnotation *TemplateId = new (std::malloc(
|
||||
totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
|
||||
TemplateIdAnnotation(SS, TemplateKWLoc, TemplateNameLoc, Name,
|
||||
OperatorKind, OpaqueTemplateName, TemplateKind,
|
||||
LAngleLoc, RAngleLoc, TemplateArgs);
|
||||
CleanupList.push_back(TemplateId);
|
||||
return TemplateId;
|
||||
}
|
||||
|
||||
void Destroy() {
|
||||
SS.~CXXScopeSpec();
|
||||
|
||||
void Destroy() {
|
||||
std::for_each(
|
||||
getTemplateArgs(), getTemplateArgs() + NumArgs,
|
||||
[](ParsedTemplateArgument &A) { A.~ParsedTemplateArgument(); });
|
||||
this->~TemplateIdAnnotation();
|
||||
free(this);
|
||||
}
|
||||
private:
|
||||
TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;
|
||||
|
||||
TemplateIdAnnotation(CXXScopeSpec SS, SourceLocation TemplateKWLoc,
|
||||
SourceLocation TemplateNameLoc, IdentifierInfo *Name,
|
||||
OverloadedOperatorKind OperatorKind,
|
||||
ParsedTemplateTy OpaqueTemplateName,
|
||||
TemplateNameKind TemplateKind,
|
||||
SourceLocation LAngleLoc, SourceLocation RAngleLoc,
|
||||
ArrayRef<ParsedTemplateArgument> TemplateArgs) noexcept
|
||||
: SS(SS), TemplateKWLoc(TemplateKWLoc),
|
||||
TemplateNameLoc(TemplateNameLoc), Name(Name), Operator(OperatorKind),
|
||||
Template(OpaqueTemplateName), Kind(TemplateKind),
|
||||
LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
|
||||
NumArgs(TemplateArgs.size()) {
|
||||
|
||||
std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(),
|
||||
getTemplateArgs());
|
||||
}
|
||||
~TemplateIdAnnotation() = default;
|
||||
};
|
||||
|
||||
/// Retrieves the range of the given template parameter lists.
|
||||
|
|
|
@ -2120,31 +2120,18 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
|
|||
Id.getKind() == UnqualifiedId::IK_LiteralOperatorId) {
|
||||
// Form a parsed representation of the template-id to be stored in the
|
||||
// UnqualifiedId.
|
||||
TemplateIdAnnotation *TemplateId
|
||||
= TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);
|
||||
|
||||
// FIXME: Store name for literal operator too.
|
||||
if (Id.getKind() == UnqualifiedId::IK_Identifier) {
|
||||
TemplateId->Name = Id.Identifier;
|
||||
TemplateId->Operator = OO_None;
|
||||
TemplateId->TemplateNameLoc = Id.StartLocation;
|
||||
} else {
|
||||
TemplateId->Name = nullptr;
|
||||
TemplateId->Operator = Id.OperatorFunctionId.Operator;
|
||||
TemplateId->TemplateNameLoc = Id.StartLocation;
|
||||
}
|
||||
IdentifierInfo *TemplateII =
|
||||
Id.getKind() == UnqualifiedId::IK_Identifier ? Id.Identifier : nullptr;
|
||||
OverloadedOperatorKind OpKind = Id.getKind() == UnqualifiedId::IK_Identifier
|
||||
? OO_None
|
||||
: Id.OperatorFunctionId.Operator;
|
||||
|
||||
TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
|
||||
SS, TemplateKWLoc, Id.StartLocation, TemplateII, OpKind, Template, TNK,
|
||||
LAngleLoc, RAngleLoc, TemplateArgs, TemplateIds);
|
||||
|
||||
TemplateId->SS = SS;
|
||||
TemplateId->TemplateKWLoc = TemplateKWLoc;
|
||||
TemplateId->Template = Template;
|
||||
TemplateId->Kind = TNK;
|
||||
TemplateId->LAngleLoc = LAngleLoc;
|
||||
TemplateId->RAngleLoc = RAngleLoc;
|
||||
ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
|
||||
for (unsigned Arg = 0, ArgEnd = TemplateArgs.size();
|
||||
Arg != ArgEnd; ++Arg)
|
||||
Args[Arg] = TemplateArgs[Arg];
|
||||
|
||||
Id.setTemplateId(TemplateId);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1011,25 +1011,21 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
|
|||
// Build a template-id annotation token that can be processed
|
||||
// later.
|
||||
Tok.setKind(tok::annot_template_id);
|
||||
TemplateIdAnnotation *TemplateId
|
||||
= TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);
|
||||
TemplateId->TemplateNameLoc = TemplateNameLoc;
|
||||
if (TemplateName.getKind() == UnqualifiedId::IK_Identifier) {
|
||||
TemplateId->Name = TemplateName.Identifier;
|
||||
TemplateId->Operator = OO_None;
|
||||
} else {
|
||||
TemplateId->Name = nullptr;
|
||||
TemplateId->Operator = TemplateName.OperatorFunctionId.Operator;
|
||||
}
|
||||
TemplateId->SS = SS;
|
||||
TemplateId->TemplateKWLoc = TemplateKWLoc;
|
||||
TemplateId->Template = Template;
|
||||
TemplateId->Kind = TNK;
|
||||
TemplateId->LAngleLoc = LAngleLoc;
|
||||
TemplateId->RAngleLoc = RAngleLoc;
|
||||
ParsedTemplateArgument *Args = TemplateId->getTemplateArgs();
|
||||
for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg)
|
||||
Args[Arg] = ParsedTemplateArgument(TemplateArgs[Arg]);
|
||||
|
||||
IdentifierInfo *TemplateII =
|
||||
TemplateName.getKind() == UnqualifiedId::IK_Identifier
|
||||
? TemplateName.Identifier
|
||||
: nullptr;
|
||||
|
||||
OverloadedOperatorKind OpKind =
|
||||
TemplateName.getKind() == UnqualifiedId::IK_Identifier
|
||||
? OO_None
|
||||
: TemplateName.OperatorFunctionId.Operator;
|
||||
|
||||
TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
|
||||
SS, TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
|
||||
LAngleLoc, RAngleLoc, TemplateArgs, TemplateIds);
|
||||
|
||||
Tok.setAnnotationValue(TemplateId);
|
||||
if (TemplateKWLoc.isValid())
|
||||
Tok.setLocation(TemplateKWLoc);
|
||||
|
|
Loading…
Reference in New Issue