Skip to content

Commit

Permalink
Started implementing variable templates. Top level declarations shoul…
Browse files Browse the repository at this point in the history
…d be fully supported, up to some limitations documented as FIXMEs or TODO. Static data member templates work very partially. Static data member templates of class templates need particular attention...

llvm-svn: 187762
  • Loading branch information
lvoufo committed Aug 6, 2013
1 parent 6f7213c commit 39a1e50
Show file tree
Hide file tree
Showing 51 changed files with 4,445 additions and 415 deletions.
35 changes: 27 additions & 8 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,13 +271,25 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// wasting space in the Decl class.
llvm::DenseMap<const Decl*, AttrVec*> DeclAttrs;

/// \brief Keeps track of the static data member templates from which
/// static data members of class template specializations were instantiated.
public:
/// \brief A type synonym for the TemplateOrInstantiation mapping.
typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>
TemplateOrSpecializationInfo;

private:

/// \brief A mapping to contain the template or declaration that
/// a variable declaration describes or was instantiated from,
/// respectively.
///
/// This data structure stores the mapping from instantiations of static
/// data members to the static data member representations within the
/// class template from which they were instantiated along with the kind
/// of instantiation or specialization (a TemplateSpecializationKind - 1).
/// For non-templates, this value will be NULL. For variable
/// declarations that describe a variable template, this will be a
/// pointer to a VarTemplateDecl. For static data members
/// of class template specializations, this will be the
/// MemberSpecializationInfo referring to the member variable that was
/// instantiated or specialized. Thus, the mapping will keep track of
/// the static data member templates from which static data members of
/// class template specializations were instantiated.
///
/// Given the following example:
///
Expand All @@ -296,8 +308,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// This mapping will contain an entry that maps from the VarDecl for
/// X<int>::value to the corresponding VarDecl for X<T>::value (within the
/// class template X) and will be marked TSK_ImplicitInstantiation.
llvm::DenseMap<const VarDecl *, MemberSpecializationInfo *>
InstantiatedFromStaticDataMember;
llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>
TemplateOrInstantiation;

/// \brief Keeps track of the declaration from which a UsingDecl was
/// created during instantiation.
Expand Down Expand Up @@ -606,9 +618,13 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
/// from which it was instantiated.
// FIXME: Remove ?
MemberSpecializationInfo *getInstantiatedFromStaticDataMember(
const VarDecl *Var);

TemplateOrSpecializationInfo
getTemplateOrSpecializationInfo(const VarDecl *Var);

FunctionDecl *getClassScopeSpecializationPattern(const FunctionDecl *FD);

void setClassScopeSpecializationPattern(FunctionDecl *FD,
Expand All @@ -620,6 +636,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
TemplateSpecializationKind TSK,
SourceLocation PointOfInstantiation = SourceLocation());

void setTemplateOrSpecializationInfo(VarDecl *Inst,
TemplateOrSpecializationInfo TSI);

/// \brief If the given using decl \p Inst is an instantiation of a
/// (possibly unresolved) using decl from a template instantiation,
/// return it.
Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang/AST/ASTMutationListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ namespace clang {
class QualType;
class TagDecl;
class VarDecl;
class VarTemplateDecl;
class VarTemplateSpecializationDecl;

/// \brief An abstract interface that should be implemented by listeners
/// that want to be notified when an AST entity gets modified after its
Expand All @@ -52,6 +54,12 @@ class ASTMutationListener {
virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
const ClassTemplateSpecializationDecl *D) {}

/// \brief A template specialization (or partial one) was added to the
/// template declaration.
virtual void
AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
const VarTemplateSpecializationDecl *D) {}

/// \brief A template specialization (or partial one) was added to the
/// template declaration.
virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
Expand Down
36 changes: 26 additions & 10 deletions clang/include/clang/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class TemplateArgumentList;
class TemplateParameterList;
class TypeLoc;
class UnresolvedSetImpl;
class VarTemplateDecl;

/// \brief A container of type source information.
///
Expand Down Expand Up @@ -710,6 +711,7 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {

friend class ASTDeclReader;
friend class StmtIteratorBase;
friend class ASTNodeImporter;

protected:
enum { NumParameterIndexBits = 8 };
Expand Down Expand Up @@ -748,15 +750,8 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
};

VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, StorageClass SC)
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() {
assert(sizeof(VarDeclBitfields) <= sizeof(unsigned));
assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned));
AllBits = 0;
VarDeclBits.SClass = SC;
// Everything else is implicitly initialized to false.
}
SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, StorageClass SC);

typedef Redeclarable<VarDecl> redeclarable_base;
virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
Expand Down Expand Up @@ -955,7 +950,8 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {

/// isFileVarDecl - Returns true for file scoped variable declaration.
bool isFileVarDecl() const {
if (getKind() != Decl::Var)
Kind K = getKind();
if (K == ParmVar || K == ImplicitParam)
return false;

if (getDeclContext()->getRedeclContext()->isFileContext())
Expand Down Expand Up @@ -1150,6 +1146,26 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
SourceLocation PointOfInstantiation = SourceLocation());

/// \brief Specify that this variable is an instantiation of the
/// static data member VD.
void setInstantiationOfStaticDataMember(VarDecl *VD,
TemplateSpecializationKind TSK);

/// \brief Retrieves the variable template that is described by this
/// variable declaration.
///
/// Every variable template is represented as a VarTemplateDecl and a
/// VarDecl. The former contains template properties (such as
/// the template parameter lists) while the latter contains the
/// actual description of the template's
/// contents. VarTemplateDecl::getTemplatedDecl() retrieves the
/// VarDecl that from a VarTemplateDecl, while
/// getDescribedVarTemplate() retrieves the VarTemplateDecl from
/// a VarDecl.
VarTemplateDecl *getDescribedVarTemplate() const;

void setDescribedVarTemplate(VarTemplateDecl *Template);

// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }
Expand Down
Loading

0 comments on commit 39a1e50

Please sign in to comment.