You've already forked linux-packaging-mono
247 lines
9.3 KiB
C++
247 lines
9.3 KiB
C++
//===--- ParsedTemplate.h - Template Parsing Data Types ---------*- C++ -*-===//
|
|
//
|
|
// 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_SEMA_PARSEDTEMPLATE_H
|
|
#define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
|
|
|
|
#include "clang/Basic/OperatorKinds.h"
|
|
#include "clang/Basic/SourceLocation.h"
|
|
#include "clang/Basic/TemplateKinds.h"
|
|
#include "clang/Sema/DeclSpec.h"
|
|
#include "clang/Sema/Ownership.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include <cassert>
|
|
#include <cstdlib>
|
|
#include <new>
|
|
|
|
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 is invalid.
|
|
ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
|
|
|
|
/// \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,
|
|
ParsedTemplateTy Template,
|
|
SourceLocation TemplateLoc)
|
|
: Kind(ParsedTemplateArgument::Template),
|
|
Arg(Template.getAsOpaquePtr()),
|
|
SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
|
|
|
|
/// \brief Determine whether the given template argument is invalid.
|
|
bool isInvalid() const { return Arg == nullptr; }
|
|
|
|
/// \brief Determine what kind of template argument we have.
|
|
KindType getKind() const { return Kind; }
|
|
|
|
/// \brief Retrieve the template type argument's type.
|
|
ParsedType getAsType() const {
|
|
assert(Kind == Type && "Not a template type argument");
|
|
return ParsedType::getFromOpaquePtr(Arg);
|
|
}
|
|
|
|
/// \brief Retrieve the non-type template argument's expression.
|
|
Expr *getAsExpr() const {
|
|
assert(Kind == NonType && "Not a non-type template argument");
|
|
return static_cast<Expr*>(Arg);
|
|
}
|
|
|
|
/// \brief Retrieve the template template argument's template name.
|
|
ParsedTemplateTy getAsTemplate() const {
|
|
assert(Kind == Template && "Not a template template argument");
|
|
return ParsedTemplateTy::getFromOpaquePtr(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;
|
|
}
|
|
|
|
/// \brief Retrieve the location of the ellipsis that makes a template
|
|
/// template argument into a pack expansion.
|
|
SourceLocation getEllipsisLoc() const {
|
|
assert(Kind == Template &&
|
|
"Only template template arguments can have an ellipsis");
|
|
return EllipsisLoc;
|
|
}
|
|
|
|
/// \brief Retrieve a pack expansion of the given template template
|
|
/// argument.
|
|
///
|
|
/// \param EllipsisLoc The location of the ellipsis.
|
|
ParsedTemplateArgument getTemplatePackExpansion(
|
|
SourceLocation EllipsisLoc) const;
|
|
|
|
private:
|
|
KindType Kind;
|
|
|
|
/// \brief The actual template argument representation, which may be
|
|
/// an \c Sema::TypeTy* (for a type), an Expr* (for an
|
|
/// expression), or an Sema::TemplateTy (for a template).
|
|
void *Arg;
|
|
|
|
/// \brief The nested-name-specifier that can accompany a template template
|
|
/// argument.
|
|
CXXScopeSpec SS;
|
|
|
|
/// \brief the location of the template argument.
|
|
SourceLocation Loc;
|
|
|
|
/// \brief The ellipsis location that can accompany a template template
|
|
/// argument (turning it into a template template argument expansion).
|
|
SourceLocation EllipsisLoc;
|
|
};
|
|
|
|
/// \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 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.
|
|
/// For e.g. typename T::template Y<U>
|
|
SourceLocation TemplateKWLoc;
|
|
|
|
/// 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.
|
|
ParsedTemplateTy 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 getTrailingObjects<ParsedTemplateArgument>();
|
|
}
|
|
|
|
/// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
|
|
/// appends it to List.
|
|
static TemplateIdAnnotation *
|
|
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() {
|
|
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.
|
|
SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
|
|
unsigned NumParams);
|
|
} // end namespace clang
|
|
|
|
#endif // LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
|