]> granicus.if.org Git - clang/commitdiff
Move the management of the set of conversion functions in a C++ class
authorDouglas Gregor <dgregor@apple.com>
Wed, 29 Sep 2010 04:25:11 +0000 (04:25 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 29 Sep 2010 04:25:11 +0000 (04:25 +0000)
into CXXRecordDecl. The only part that we do not handle this way are
using declarations, since that would require extra name lookup that we
don't currently want to pay for. This fixes <rdar://problem/8459981>,
so that LLDB can build a CXXRecordDecl and magically get all of the
right bits set.

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

include/clang/AST/DeclCXX.h
lib/AST/DeclCXX.cpp
lib/Sema/SemaDeclCXX.cpp

index 052cbe8cb418d598ed881ec48349ea338d2269fa..9c2d497c210a3cd8db58ed80b12e5a0c49a37403 100644 (file)
@@ -657,13 +657,6 @@ public:
     return getConversionFunctions()->end();
   }
 
-  /// Replaces a conversion function with a new declaration.
-  ///
-  /// Returns true if the old conversion was found.
-  bool replaceConversion(const NamedDecl* Old, NamedDecl *New) {
-    return getConversionFunctions()->replace(Old, New);
-  }
-
   /// Removes a conversion function from this class.  The conversion
   /// function must currently be a member of this class.  Furthermore,
   /// this class must currently be in the process of being defined.
@@ -673,18 +666,6 @@ public:
   /// in current class; including conversion function templates.
   const UnresolvedSetImpl *getVisibleConversionFunctions();
 
-  /// addConversionFunction - Registers a conversion function which
-  /// this class declares directly.
-  void addConversionFunction(NamedDecl *Decl) {
-#ifndef NDEBUG
-    CheckConversionFunction(Decl);
-#endif
-
-    // We intentionally don't use the decl's access here because it
-    // hasn't been set yet.  That's really just a misdesign in Sema.
-    data().Conversions.addDecl(Decl);
-  }
-
   /// isAggregate - Whether this class is an aggregate (C++
   /// [dcl.init.aggr]), which is a class with no user-declared
   /// constructors, no private or protected non-static data members,
index 6e879ee9ee48984e4602e001933f91adfff2169b..19caae5b7f2b37b12289a98041e364623afcd58e 100644 (file)
@@ -493,6 +493,30 @@ void CXXRecordDecl::addedMember(Decl *D) {
       data().PlainOldData = false;
     }
     
+    // Keep the list of conversion functions up-to-date.
+    if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
+      // We don't record specializations.
+      if (Conversion->getPrimaryTemplate())
+        return;
+      
+      // FIXME: We intentionally don't use the decl's access here because it
+      // hasn't been set yet.  That's really just a misdesign in Sema.
+
+      if (FunTmpl) {
+        if (FunTmpl->getPreviousDeclaration())
+          data().Conversions.replace(FunTmpl->getPreviousDeclaration(),
+                                     FunTmpl);
+        else
+          data().Conversions.addDecl(FunTmpl);
+      } else {
+        if (Conversion->getPreviousDeclaration())
+          data().Conversions.replace(Conversion->getPreviousDeclaration(),
+                                     Conversion);
+        else
+          data().Conversions.addDecl(Conversion);        
+      }
+    }
+    
     return;
   }
   
@@ -546,6 +570,12 @@ void CXXRecordDecl::addedMember(Decl *D) {
       } 
     }
   }
+  
+  // Handle using declarations of conversion functions.
+  if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(D))
+    if (Shadow->getDeclName().getNameKind()
+          == DeclarationName::CXXConversionFunctionName)
+      data().Conversions.addDecl(Shadow, Shadow->getAccess());
 }
 
 static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) {
@@ -833,6 +863,12 @@ void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
       }
     }
   }
+  
+  // Set access bits correctly on the directly-declared conversions.
+  for (UnresolvedSetIterator I = data().Conversions.begin(), 
+                             E = data().Conversions.end(); 
+       I != E; ++I)
+    data().Conversions.setAccess(I, (*I)->getAccess());
 }
 
 bool CXXRecordDecl::mayBeAbstract() const {
index e0049e636fc09dafa7730a3311d45162d9a24282..1e4065454ed827228bd3bfb8e6686d1c965db459 100644 (file)
@@ -3107,25 +3107,10 @@ Decl *Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
       << ClassType << ConvType;
   }
 
-  if (Conversion->getPrimaryTemplate()) {
-    // ignore specializations
-  } else if (Conversion->getPreviousDeclaration()) {
-    if (FunctionTemplateDecl *ConversionTemplate
-                                  = Conversion->getDescribedFunctionTemplate()) {
-      if (ClassDecl->replaceConversion(
-                                   ConversionTemplate->getPreviousDeclaration(),
-                                       ConversionTemplate))
-        return ConversionTemplate;
-    } else if (ClassDecl->replaceConversion(Conversion->getPreviousDeclaration(),
-                                            Conversion))
-      return Conversion;
-    assert(Conversion->isInvalidDecl() && "Conversion should not get here.");
-  } else if (FunctionTemplateDecl *ConversionTemplate
-               = Conversion->getDescribedFunctionTemplate())
-    ClassDecl->addConversionFunction(ConversionTemplate);
-  else 
-    ClassDecl->addConversionFunction(Conversion);
-
+  if (FunctionTemplateDecl *ConversionTemplate
+                                = Conversion->getDescribedFunctionTemplate())
+    return ConversionTemplate;
+  
   return Conversion;
 }
 
@@ -3669,20 +3654,16 @@ UsingShadowDecl *Sema::BuildUsingShadowDecl(Scope *S,
     = UsingShadowDecl::Create(Context, CurContext,
                               UD->getLocation(), UD, Target);
   UD->addShadowDecl(Shadow);
-
+  
+  Shadow->setAccess(UD->getAccess());
+  if (Orig->isInvalidDecl() || UD->isInvalidDecl())
+    Shadow->setInvalidDecl();
+  
   if (S)
     PushOnScopeChains(Shadow, S);
   else
     CurContext->addDecl(Shadow);
-  Shadow->setAccess(UD->getAccess());
 
-  // Register it as a conversion if appropriate.
-  if (Shadow->getDeclName().getNameKind()
-        == DeclarationName::CXXConversionFunctionName)
-    cast<CXXRecordDecl>(CurContext)->addConversionFunction(Shadow);
-
-  if (Orig->isInvalidDecl() || UD->isInvalidDecl())
-    Shadow->setInvalidDecl();
 
   return Shadow;
 }