[cfe-commits] r80657 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Sema/TreeTransform.h test/SemaTemplate/instantiate-anonymous-union.cpp

Anders Carlsson andersca at mac.com
Mon Aug 31 21:26:59 PDT 2009


Author: andersca
Date: Mon Aug 31 23:26:58 2009
New Revision: 80657

URL: http://llvm.org/viewvc/llvm-project?rev=80657&view=rev
Log:
Don't assert when instantiating member references to fields in anonymous structs.

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/SemaTemplate/instantiate-anonymous-union.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=80657&r1=80656&r2=80657&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Aug 31 23:26:58 2009
@@ -196,6 +196,8 @@
   llvm::DenseMap<UsingDecl *, UnresolvedUsingDecl *>
     InstantiatedFromUnresolvedUsingDecl;
   
+  llvm::DenseMap<FieldDecl *, FieldDecl *> InstantiatedFromUnnamedFieldDecl;
+  
   TranslationUnitDecl *TUDecl;
 
   /// SourceMgr - The associated SourceManager object.
@@ -267,12 +269,23 @@
   /// the static data member template \p Tmpl of a class template.
   void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl);  
   
+  /// \brief If this using decl is instantiated from an unresolved using decl,
+  /// return it.
   UnresolvedUsingDecl *getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD);
-  void setInstantiatedFromUnresolvedUsingDecl(UsingDecl *UD,
-                                              UnresolvedUsingDecl *UUD);
+
+  /// \brief Note that the using decl \p Inst is an instantiation of
+  /// the unresolved using decl \p Tmpl of a class template.
+  void setInstantiatedFromUnresolvedUsingDecl(UsingDecl *Inst,
+                                              UnresolvedUsingDecl *Tmpl);
+  
+  
+  FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
+  
+  void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
   
   TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
 
+  
   const char *getCommentForDecl(const Decl *D);
   
   // Builtin Types.

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=80657&r1=80656&r2=80657&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Aug 31 23:26:58 2009
@@ -260,6 +260,25 @@
   InstantiatedFromUnresolvedUsingDecl[UD] = UUD;
 }
 
+FieldDecl *ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) {
+  llvm::DenseMap<FieldDecl *, FieldDecl *>::iterator Pos
+    = InstantiatedFromUnnamedFieldDecl.find(Field);
+  if (Pos == InstantiatedFromUnnamedFieldDecl.end())
+    return 0;
+  
+  return Pos->second;
+}
+
+void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst,
+                                                     FieldDecl *Tmpl) {
+  assert(!Inst->getDeclName() && "Instantiated field decl is not unnamed");
+  assert(!Tmpl->getDeclName() && "Template field decl is not unnamed");
+  assert(!InstantiatedFromUnnamedFieldDecl[Inst] &&
+         "Already noted what unnamed field was instantiated from");
+  
+  InstantiatedFromUnnamedFieldDecl[Inst] = Tmpl;
+}
+
 namespace {
   class BeforeInTranslationUnit 
     : std::binary_function<SourceRange, SourceRange, bool> {

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=80657&r1=80656&r2=80657&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Aug 31 23:26:58 2009
@@ -245,6 +245,11 @@
     if (Invalid)
       Field->setInvalidDecl();
     
+    if (!Field->getDeclName()) {
+      // Keep track of where this decl came from.
+      SemaRef.Context.setInstantiatedFromUnnamedFieldDecl(Field, D);
+    }
+    
     Owner->addDecl(Field);
   }
 
@@ -441,6 +446,8 @@
   if (Decl::FriendObjectKind FOK = D->getFriendObjectKind())
     Record->setObjectOfFriendDecl(FOK == Decl::FOK_Declared);
 
+  Record->setAnonymousStructOrUnion(D->isAnonymousStructOrUnion());
+
   Owner->addDecl(Record);
   return Record;
 }
@@ -1274,8 +1281,14 @@
   if (ClassTemplateDecl *Temp = dyn_cast<ClassTemplateDecl>(Other))
     return isInstantiationOf(cast<ClassTemplateDecl>(D), Temp);
 
-  // FIXME: How can we find instantiations of anonymous unions?
-
+  if (FieldDecl *Field = dyn_cast<FieldDecl>(Other)) {
+    if (!Field->getDeclName()) {
+      // This is an unnamed field.
+      return Ctx.getInstantiatedFromUnnamedFieldDecl(Field) == 
+        cast<FieldDecl>(D);
+    }
+  }
+  
   return D->getDeclName() && isa<NamedDecl>(Other) &&
     D->getDeclName() == cast<NamedDecl>(Other)->getDeclName();
 }

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=80657&r1=80656&r2=80657&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Aug 31 23:26:58 2009
@@ -840,6 +840,17 @@
                                      SourceRange QualifierRange,
                                      SourceLocation MemberLoc,
                                      NamedDecl *Member) {
+    if (!Member->getDeclName()) {
+      // We have a reference to an unnamed field.
+      assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
+      
+      MemberExpr *ME = 
+        new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
+                                           Member, MemberLoc,
+                                           cast<FieldDecl>(Member)->getType());
+      return getSema().Owned(ME);
+    }
+      
     CXXScopeSpec SS;
     if (Qualifier) {
       SS.setRange(QualifierRange);

Modified: cfe/trunk/test/SemaTemplate/instantiate-anonymous-union.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-anonymous-union.cpp?rev=80657&r1=80656&r2=80657&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-anonymous-union.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-anonymous-union.cpp Mon Aug 31 23:26:58 2009
@@ -6,3 +6,16 @@
 
 A<int> a0;
 
+template <typename T> struct B {
+  union {
+    int a;
+    void* b;
+  };
+    
+  void f() {
+    a = 10;
+    b = 0;
+  }
+};
+
+B<int> b0;





More information about the cfe-commits mailing list