]> granicus.if.org Git - clang/commitdiff
Enumeration declarations that were instantiated from an enumeration
authorDouglas Gregor <dgregor@apple.com>
Wed, 27 May 2009 17:20:35 +0000 (17:20 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 27 May 2009 17:20:35 +0000 (17:20 +0000)
within a template now have a link back to the enumeration from which
they were instantiated. This means that we can now find the
instantiation of an anonymous enumeration.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72482 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Decl.h
lib/Frontend/PCHReaderDecl.cpp
lib/Frontend/PCHWriterDecl.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaTemplate/instantiate-declref.cpp

index a30cf0fbc50ba287b547223a1ab6737ec1367906..eb38367436bd369050768024e0bf367a35f41e9a 100644 (file)
@@ -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; }
 };
index adf0d1155e23899b399c5dd97a5bdf930398b2f9..6856623e60c965015f6348655192f296d7b9845c 100644 (file)
@@ -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) {
index 5d08334dee82f379cb829529c3725db75f84dd7f..ef04104316905fa40e55cd41851b1f52595bb39e 100644 (file)
@@ -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;
 }
 
index a5eb7793b844cc5d62ef26fbb027e8f863290782..41c1944b541cb737717bc060dd90d0efecb30409 100644 (file)
@@ -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?
 
index 2512df15b13fbf88a514cd28ee93f8bd66ae9218..cceaed00e69da7ad1e17f92e8c313c3c433f1775 100644 (file)
@@ -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;