aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Decl.h18
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp1
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp1
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp5
-rw-r--r--test/SemaTemplate/instantiate-declref.cpp3
5 files changed, 23 insertions, 5 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index a30cf0fbc5..eb38367436 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -1149,10 +1149,15 @@ class EnumDecl : public TagDecl {
/// to for code generation purposes. Note that the enumerator constants may
/// have a different type than this does.
QualType IntegerType;
-
+
+ /// \brief If the enumeration was instantiated from an enumeration
+ /// within a class or function template, this pointer refers to the
+ /// enumeration declared within the template.
+ EnumDecl *InstantiatedFrom;
+
EnumDecl(DeclContext *DC, SourceLocation L,
IdentifierInfo *Id)
- : TagDecl(Enum, TK_enum, DC, L, Id) {
+ : TagDecl(Enum, TK_enum, DC, L, Id), InstantiatedFrom(0) {
IntegerType = QualType();
}
public:
@@ -1188,6 +1193,15 @@ public:
/// \brief Set the underlying integer type.
void setIntegerType(QualType T) { IntegerType = T; }
+ /// \brief Returns the enumeration (declared within the template)
+ /// from which this enumeration type was instantiated, or NULL if
+ /// this enumeration was not instantiated from any template.
+ EnumDecl *getInstantiatedFromMemberEnum() const {
+ return InstantiatedFrom;
+ }
+
+ void setInstantiationOfMemberEnum(EnumDecl *IF) { InstantiatedFrom = IF; }
+
static bool classof(const Decl *D) { return D->getKind() == Enum; }
static bool classof(const EnumDecl *D) { return true; }
};
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index adf0d1155e..6856623e60 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -120,6 +120,7 @@ void PCHDeclReader::VisitTagDecl(TagDecl *TD) {
void PCHDeclReader::VisitEnumDecl(EnumDecl *ED) {
VisitTagDecl(ED);
ED->setIntegerType(Reader.GetType(Record[Idx++]));
+ // FIXME: C++ InstantiatedFrom
}
void PCHDeclReader::VisitRecordDecl(RecordDecl *RD) {
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index 5d08334dee..ef04104316 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -116,6 +116,7 @@ void PCHDeclWriter::VisitTagDecl(TagDecl *D) {
void PCHDeclWriter::VisitEnumDecl(EnumDecl *D) {
VisitTagDecl(D);
Writer.AddTypeRef(D->getIntegerType(), Record);
+ // FIXME: C++ InstantiatedFrom
Code = pch::DECL_ENUM;
}
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index a5eb7793b8..41c1944b54 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -208,6 +208,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
EnumDecl *Enum = EnumDecl::Create(SemaRef.Context, Owner,
D->getLocation(), D->getIdentifier(),
/*PrevDecl=*/0);
+ Enum->setInstantiationOfMemberEnum(D);
Enum->setAccess(D->getAccess());
Owner->addDecl(SemaRef.Context, Enum);
Enum->startDefinition();
@@ -648,7 +649,9 @@ static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) {
return Ctx.getCanonicalDecl(Function->getInstantiatedFromMemberFunction())
== Ctx.getCanonicalDecl(D);
- // FIXME: Need something similar to the above for EnumDecls.
+ if (EnumDecl *Enum = dyn_cast<EnumDecl>(Other))
+ return Ctx.getCanonicalDecl(Enum->getInstantiatedFromMemberEnum())
+ == Ctx.getCanonicalDecl(D);
// FIXME: How can we find instantiations of anonymous unions?
diff --git a/test/SemaTemplate/instantiate-declref.cpp b/test/SemaTemplate/instantiate-declref.cpp
index 2512df15b1..cceaed00e6 100644
--- a/test/SemaTemplate/instantiate-declref.cpp
+++ b/test/SemaTemplate/instantiate-declref.cpp
@@ -9,8 +9,7 @@ namespace N {
typedef T type;
static enum K1 { K1Val = sizeof(T) } Kind1;
- // FIXME: Remove the name K2, below
- static enum K2 { K2Val = sizeof(T)*2 } Kind2;
+ static enum { K2Val = sizeof(T)*2 } Kind2;
void foo() {
K1 k1 = K1Val;