aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-07-24 20:34:43 +0000
committerDouglas Gregor <dgregor@apple.com>2009-07-24 20:34:43 +0000
commit7caa6825f42a0f7e97d6fc06233133c42b218e46 (patch)
tree1be851e7cede92bb39bcb037c00a6d9a9061e946 /include/clang
parent0eb7cff82f943ebcb14f1c9a2020a83a030a0893 (diff)
Template instantiation for static data members that are defined out-of-line.
Note that this also fixes a bug that affects non-template code, where we were not treating out-of-line static data members are "file-scope" variables, and therefore not checking their initializers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77002 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/ASTContext.h35
-rw-r--r--include/clang/AST/Decl.h8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
3 files changed, 45 insertions, 0 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 6af58288bb..78c6122655 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -136,6 +136,32 @@ class ASTContext {
/// wasting space in the Decl class.
llvm::DenseMap<const Decl*, Attr*> DeclAttrs;
+ /// \brief Keeps track of the static data member templates from which
+ /// static data members of class template specializations were instantiated.
+ ///
+ /// 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.
+ ///
+ /// Given the following example:
+ ///
+ /// \code
+ /// template<typename T>
+ /// struct X {
+ /// static T value;
+ /// };
+ ///
+ /// template<typename T>
+ /// T X<T>::value = T(17);
+ ///
+ /// int *x = &X<int>::value;
+ /// \endcode
+ ///
+ /// 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).
+ llvm::DenseMap<VarDecl *, VarDecl *> InstantiatedFromStaticDataMember;
+
TranslationUnitDecl *TUDecl;
/// SourceMgr - The associated SourceManager object.
@@ -193,6 +219,15 @@ public:
/// \brief Erase the attributes corresponding to the given declaration.
void eraseDeclAttrs(const Decl *D) { DeclAttrs.erase(D); }
+ /// \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.
+ VarDecl *getInstantiatedFromStaticDataMember(VarDecl *Var);
+
+ /// \brief Note that the static data member \p Inst is an instantiation of
+ /// the static data member template \p Tmpl of a class template.
+ void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl);
+
TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
const char *getCommentForDecl(const Decl *D);
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index d99873823c..f8ee70b752 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -477,6 +477,11 @@ public:
return getDeclContext()->isRecord();
}
+ /// \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.
+ VarDecl *getInstantiatedFromStaticDataMember();
+
/// isFileVarDecl - Returns true for file scoped variable declaration.
bool isFileVarDecl() const {
if (getKind() != Decl::Var)
@@ -486,6 +491,9 @@ public:
if (isa<TranslationUnitDecl>(Ctx) || isa<NamespaceDecl>(Ctx) )
return true;
}
+ if (isStaticDataMember() && isOutOfLine())
+ return true;
+
return false;
}
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 9031a6ec9c..9540091a82 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -888,6 +888,8 @@ def note_template_member_function_here : Note<
"in instantiation of member function %q0 requested here">;
def note_function_template_spec_here : Note<
"in instantiation of function template specialization %q0 requested here">;
+def note_template_static_data_member_def_here : Note<
+ "in instantiation of static data member %q0 requested here">;
def note_default_arg_instantiation_here : Note<
"in instantiation of default argument for '%0' required here">;