Skip to content

Commit

Permalink
Convert a few classes over to use the new TrailingObjects helper.
Browse files Browse the repository at this point in the history
This initial commit serves as an example -- the remainder of the
classes using pointer arithmetic for trailing objects will be
converted in subsequent changes.

Differential Revision: http://reviews.llvm.org/D11298

llvm-svn: 244262
  • Loading branch information
jyknight committed Aug 6, 2015
1 parent 7d708db commit 7a22b24
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 107 deletions.
29 changes: 22 additions & 7 deletions clang/include/clang/AST/Decl.h
Expand Up @@ -26,6 +26,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TrailingObjects.h"

namespace clang {
struct ASTTemplateArgumentListInfo;
Expand Down Expand Up @@ -3626,7 +3627,15 @@ class BlockDecl : public Decl, public DeclContext {

/// \brief This represents the body of a CapturedStmt, and serves as its
/// DeclContext.
class CapturedDecl : public Decl, public DeclContext {
class CapturedDecl final
: public Decl,
public DeclContext,
private llvm::TrailingObjects<CapturedDecl, ImplicitParamDecl *> {
protected:
size_t numTrailingObjects(OverloadToken<ImplicitParamDecl>) {
return NumParams;
}

private:
/// \brief The number of parameters to the outlined function.
unsigned NumParams;
Expand All @@ -3639,9 +3648,12 @@ class CapturedDecl : public Decl, public DeclContext {
: Decl(Captured, DC, SourceLocation()), DeclContext(Captured),
NumParams(NumParams), ContextParam(0), BodyAndNothrow(nullptr, false) { }

ImplicitParamDecl **getParams() const {
return reinterpret_cast<ImplicitParamDecl **>(
const_cast<CapturedDecl *>(this) + 1);
ImplicitParamDecl *const *getParams() const {
return getTrailingObjects<ImplicitParamDecl *>();
}

ImplicitParamDecl **getParams() {
return getTrailingObjects<ImplicitParamDecl *>();
}

public:
Expand Down Expand Up @@ -3679,7 +3691,7 @@ class CapturedDecl : public Decl, public DeclContext {
}
unsigned getContextParamPosition() const { return ContextParam; }

typedef ImplicitParamDecl **param_iterator;
typedef ImplicitParamDecl *const *param_iterator;
typedef llvm::iterator_range<param_iterator> param_range;

/// \brief Retrieve an iterator pointing to the first parameter decl.
Expand All @@ -3702,6 +3714,7 @@ class CapturedDecl : public Decl, public DeclContext {

friend class ASTDeclReader;
friend class ASTDeclWriter;
friend TrailingObjects;
};

/// \brief Describes a module import declaration, which makes the contents
Expand All @@ -3714,7 +3727,8 @@ class CapturedDecl : public Decl, public DeclContext {
///
/// Import declarations can also be implicitly generated from
/// \#include/\#import directives.
class ImportDecl : public Decl {
class ImportDecl final : public Decl,
llvm::TrailingObjects<ImportDecl, SourceLocation> {
/// \brief The imported module, along with a bit that indicates whether
/// we have source-location information for each identifier in the module
/// name.
Expand All @@ -3730,7 +3744,8 @@ class ImportDecl : public Decl {
friend class ASTReader;
friend class ASTDeclReader;
friend class ASTContext;

friend TrailingObjects;

ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported,
ArrayRef<SourceLocation> IdentifierLocs);

Expand Down
116 changes: 84 additions & 32 deletions clang/include/clang/AST/DeclTemplate.h
Expand Up @@ -20,6 +20,7 @@
#include "clang/AST/TemplateBase.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
#include <limits>

namespace clang {
Expand All @@ -43,7 +44,9 @@ typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,

/// \brief Stores a list of template parameters for a TemplateDecl and its
/// derived classes.
class LLVM_ALIGNAS(/*alignof(void*)*/ LLVM_PTR_SIZE) TemplateParameterList {
class LLVM_ALIGNAS(/*alignof(void*)*/ LLVM_PTR_SIZE) TemplateParameterList final
: private llvm::TrailingObjects<TemplateParameterList, NamedDecl *> {

/// The location of the 'template' keyword.
SourceLocation TemplateLoc;

Expand All @@ -59,6 +62,10 @@ class LLVM_ALIGNAS(/*alignof(void*)*/ LLVM_PTR_SIZE) TemplateParameterList {
unsigned ContainsUnexpandedParameterPack : 1;

protected:
size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
return NumParams;
}

TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
NamedDecl **Params, unsigned NumParams,
SourceLocation RAngleLoc);
Expand All @@ -77,10 +84,8 @@ class LLVM_ALIGNAS(/*alignof(void*)*/ LLVM_PTR_SIZE) TemplateParameterList {
/// \brief Iterates through the template parameters in this list.
typedef NamedDecl* const* const_iterator;

iterator begin() { return reinterpret_cast<NamedDecl **>(this + 1); }
const_iterator begin() const {
return reinterpret_cast<NamedDecl * const *>(this + 1);
}
iterator begin() { return getTrailingObjects<NamedDecl *>(); }
const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
iterator end() { return begin() + NumParams; }
const_iterator end() const { return begin() + NumParams; }

Expand Down Expand Up @@ -130,24 +135,43 @@ class LLVM_ALIGNAS(/*alignof(void*)*/ LLVM_PTR_SIZE) TemplateParameterList {
SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(TemplateLoc, RAngleLoc);
}

friend TrailingObjects;
template <size_t N> friend class FixedSizeTemplateParameterListStorage;
};

/// \brief Stores a list of template parameters for a TemplateDecl and its
/// derived classes. Suitable for creating on the stack.
template<size_t N>
class FixedSizeTemplateParameterList : public TemplateParameterList {
template <size_t N> class FixedSizeTemplateParameterListStorage {
// This is kinda ugly: TemplateParameterList usually gets allocated
// in a block of memory with NamedDecls appended to it. Here, to get
// it stack allocated, we include the params as a separate
// variable. After allocation, the TemplateParameterList object
// treats them as part of itself.
TemplateParameterList List;
NamedDecl *Params[N];

public:
FixedSizeTemplateParameterList(SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
NamedDecl **Params, SourceLocation RAngleLoc) :
TemplateParameterList(TemplateLoc, LAngleLoc, Params, N, RAngleLoc) {
}
FixedSizeTemplateParameterListStorage(SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
NamedDecl **Params,
SourceLocation RAngleLoc)
: List(TemplateLoc, LAngleLoc, Params, N, RAngleLoc) {
// Because we're doing an evil layout hack above, have some
// asserts, just to double-check everything is laid out like
// expected.
assert(sizeof(*this) ==
TemplateParameterList::totalSizeToAlloc<NamedDecl *>(N) &&
"Object layout not as expected");
assert(this->Params == List.getTrailingObjects<NamedDecl *>() &&
"Object layout not as expected");
}
TemplateParameterList *get() { return &List; }
};

/// \brief A template argument list.
class TemplateArgumentList {
class TemplateArgumentList final
: private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
/// \brief The template argument list.
const TemplateArgument *Arguments;

Expand All @@ -158,8 +182,9 @@ class TemplateArgumentList {
TemplateArgumentList(const TemplateArgumentList &Other) = delete;
void operator=(const TemplateArgumentList &Other) = delete;

TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs)
: Arguments(Args), NumArguments(NumArgs) { }
// Constructs an instance with an internal Argument list, containing
// a copy of the Args array. (Called by CreateCopy)
TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs);

public:
/// \brief Type used to indicate that the template argument list itself is a
Expand Down Expand Up @@ -209,6 +234,8 @@ class TemplateArgumentList {

/// \brief Retrieve a pointer to the template argument list.
const TemplateArgument *data() const { return Arguments; }

friend TrailingObjects;
};

void *allocateDefaultArgStorageChain(const ASTContext &C);
Expand Down Expand Up @@ -537,7 +564,10 @@ class MemberSpecializationInfo {
/// };
/// \endcode
class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8)
DependentFunctionTemplateSpecializationInfo {
DependentFunctionTemplateSpecializationInfo final
: private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
TemplateArgumentLoc,
FunctionTemplateDecl *> {
/// The number of potential template candidates.
unsigned NumTemplates;

Expand All @@ -547,29 +577,35 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8)
/// The locations of the left and right angle brackets.
SourceRange AngleLocs;

FunctionTemplateDecl * const *getTemplates() const {
return reinterpret_cast<FunctionTemplateDecl *const *>(
&getTemplateArgs()[NumArgs]);
size_t numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const {
return NumArgs;
}
size_t numTrailingObjects(OverloadToken<FunctionTemplateDecl *>) const {
return NumTemplates;
}

public:
DependentFunctionTemplateSpecializationInfo(
const UnresolvedSetImpl &Templates,
const TemplateArgumentListInfo &TemplateArgs);

public:
static DependentFunctionTemplateSpecializationInfo *
Create(ASTContext &Context, const UnresolvedSetImpl &Templates,
const TemplateArgumentListInfo &TemplateArgs);

/// \brief Returns the number of function templates that this might
/// be a specialization of.
unsigned getNumTemplates() const { return NumTemplates; }

/// \brief Returns the i'th template candidate.
FunctionTemplateDecl *getTemplate(unsigned I) const {
assert(I < getNumTemplates() && "template index out of range");
return getTemplates()[I];
return getTrailingObjects<FunctionTemplateDecl *>()[I];
}

/// \brief Returns the explicit template arguments that were given.
const TemplateArgumentLoc *getTemplateArgs() const {
return reinterpret_cast<const TemplateArgumentLoc *>(this + 1);
return getTrailingObjects<TemplateArgumentLoc>();
}

/// \brief Returns the number of explicit template arguments that were given.
Expand All @@ -588,6 +624,8 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8)
SourceLocation getRAngleLoc() const {
return AngleLocs.getEnd();
}

friend TrailingObjects;
};

/// Declaration of a redeclarable template.
Expand Down Expand Up @@ -1102,8 +1140,11 @@ class TemplateTypeParmDecl : public TypeDecl {
/// @code
/// template<int Size> class array { };
/// @endcode
class NonTypeTemplateParmDecl
: public DeclaratorDecl, protected TemplateParmPosition {
class NonTypeTemplateParmDecl final
: public DeclaratorDecl,
protected TemplateParmPosition,
private llvm::TrailingObjects<NonTypeTemplateParmDecl,
std::pair<QualType, TypeSourceInfo *>> {
/// \brief The default template argument, if any, and whether or not
/// it was inherited.
typedef DefaultArgStorage<NonTypeTemplateParmDecl, Expr*> DefArgStorage;
Expand All @@ -1123,6 +1164,11 @@ class NonTypeTemplateParmDecl
/// \brief The number of types in an expanded parameter pack.
unsigned NumExpandedTypes;

size_t numTrailingObjects(
OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
return NumExpandedTypes;
}

NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, unsigned D, unsigned P,
IdentifierInfo *Id, QualType T,
Expand All @@ -1141,6 +1187,7 @@ class NonTypeTemplateParmDecl
TypeSourceInfo **ExpandedTInfos);

friend class ASTDeclReader;
friend TrailingObjects;

public:
static NonTypeTemplateParmDecl *
Expand Down Expand Up @@ -1256,16 +1303,18 @@ class NonTypeTemplateParmDecl
/// pack.
QualType getExpansionType(unsigned I) const {
assert(I < NumExpandedTypes && "Out-of-range expansion type index");
void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
return QualType::getFromOpaquePtr(TypesAndInfos[2*I]);
auto TypesAndInfos =
getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
return TypesAndInfos[I].first;
}

/// \brief Retrieve a particular expansion type source info within an
/// expanded parameter pack.
TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const {
assert(I < NumExpandedTypes && "Out-of-range expansion type index");
void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
return static_cast<TypeSourceInfo *>(TypesAndInfos[2*I+1]);
auto TypesAndInfos =
getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
return TypesAndInfos[I].second;
}

// Implement isa/cast/dyncast/etc.
Expand All @@ -1280,9 +1329,11 @@ class NonTypeTemplateParmDecl
/// @endcode
/// A template template parameter is a TemplateDecl because it defines the
/// name of a template and the template parameters allowable for substitution.
class TemplateTemplateParmDecl : public TemplateDecl,
protected TemplateParmPosition
{
class TemplateTemplateParmDecl final
: public TemplateDecl,
protected TemplateParmPosition,
private llvm::TrailingObjects<TemplateTemplateParmDecl,
TemplateParameterList *> {
void anchor() override;

/// \brief The default template argument, if any.
Expand Down Expand Up @@ -1386,7 +1437,7 @@ class TemplateTemplateParmDecl : public TemplateDecl,
/// pack.
TemplateParameterList *getExpansionTemplateParameters(unsigned I) const {
assert(I < NumExpandedParams && "Out-of-range expansion type index");
return reinterpret_cast<TemplateParameterList *const *>(this + 1)[I];
return getTrailingObjects<TemplateParameterList *>()[I];
}

const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
Expand Down Expand Up @@ -1436,6 +1487,7 @@ class TemplateTemplateParmDecl : public TemplateDecl,

friend class ASTDeclReader;
friend class ASTDeclWriter;
friend TrailingObjects;
};

/// \brief Represents a class template specialization, which refers to
Expand Down

0 comments on commit 7a22b24

Please sign in to comment.