[cfe-commits] r132622 - in /cfe/trunk: include/clang/AST/Type.h include/clang/Sema/Sema.h lib/Sema/SemaLookup.cpp

Sean Hunt scshunt at csclub.uwaterloo.ca
Fri Jun 3 21:32:43 PDT 2011


Author: coppro
Date: Fri Jun  3 23:32:43 2011
New Revision: 132622

URL: http://llvm.org/viewvc/llvm-project?rev=132622&view=rev
Log:
Reimplement r132572 on top of a FoldingSet, thus hopefully solving both
the self-host failures and Chandler's concerns.

Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaLookup.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=132622&r1=132621&r2=132622&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Fri Jun  3 23:32:43 2011
@@ -538,6 +538,14 @@
     return withFastQualifiers(Qualifiers::Const);
   }
 
+  /// addVolatile - add the specified type qualifier to this QualType.  
+  void addVolatile() {
+    addFastQualifiers(Qualifiers::Volatile);
+  }
+  QualType withVolatile() const {
+    return withFastQualifiers(Qualifiers::Volatile);
+  }
+
   void addFastQualifiers(unsigned TQs) {
     assert(!(TQs & ~Qualifiers::FastMask)
            && "non-fast qualifier bits set in mask!");

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=132622&r1=132621&r2=132622&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Jun  3 23:32:43 2011
@@ -600,6 +600,40 @@
   /// A stack of expression evaluation contexts.
   llvm::SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
 
+  /// SpecialMemberOverloadResult - The overloading result for a special member
+  /// function.
+  ///
+  /// This is basically a wrapper around PointerIntPair. The lowest bit of the
+  /// integer is used to determine whether we have a parameter qualification
+  /// match, the second-lowest is whether we had success in resolving the
+  /// overload to a unique non-deleted function.
+  ///
+  /// The ConstParamMatch bit represents whether, when looking up a copy
+  /// constructor or assignment operator, we found a potential copy
+  /// constructor/assignment operator whose first parameter is const-qualified.
+  /// This is used for determining parameter types of other objects and is
+  /// utterly meaningless on other types of special members.
+  class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode {
+    llvm::PointerIntPair<CXXMethodDecl*, 2> Pair;
+  public:
+    SpecialMemberOverloadResult(const llvm::FoldingSetNodeID &ID)
+      : FastFoldingSetNode(ID)
+    {}
+
+    CXXMethodDecl *getMethod() const { return Pair.getPointer(); }
+    void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); }
+
+    bool hasSuccess() const { return Pair.getInt() & 0x1; }
+    void setSuccess(bool B) { Pair.setInt(B | hasConstParamMatch() << 1); }
+
+    bool hasConstParamMatch() const { return Pair.getInt() & 0x2; }
+    void setConstParamMatch(bool B) { Pair.setInt(B << 1 | hasSuccess()); }
+  };
+
+  /// \brief A cache of special member function overload resolution results
+  /// for C++ records.
+  llvm::FoldingSet<SpecialMemberOverloadResult> SpecialMemberCache;
+
   /// \brief Whether the code handled by Sema should be considered a
   /// complete translation unit or not.
   ///
@@ -1594,6 +1628,14 @@
 private:
   bool CppLookupName(LookupResult &R, Scope *S);
 
+  SpecialMemberOverloadResult *LookupSpecialMember(CXXRecordDecl *D,
+                                                   CXXSpecialMember SM,
+                                                   bool ConstArg,
+                                                   bool VolatileArg,
+                                                   bool RValueThis,
+                                                   bool ConstThis,
+                                                   bool VolatileThis);
+
 public:
   /// \brief Look up a name, looking for a single declaration.  Return
   /// null if the results were absent, ambiguous, or overloaded.

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=132622&r1=132621&r2=132622&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Fri Jun  3 23:32:43 2011
@@ -14,6 +14,7 @@
 #include "clang/Sema/Sema.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/Lookup.h"
+#include "clang/Sema/Overload.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
@@ -2136,6 +2137,57 @@
   }
 }
 
+Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D,
+                                                            CXXSpecialMember SM,
+                                                            bool ConstArg,
+                                                            bool VolatileArg,
+                                                            bool RValueThis,
+                                                            bool ConstThis,
+                                                            bool VolatileThis) {
+  D = D->getDefinition();
+  assert((D && !D->isBeingDefined()) &&
+         "doing special member lookup into record that isn't fully complete");
+  if (RValueThis || ConstThis || VolatileThis)
+    assert((SM == CXXCopyAssignment || SM == CXXMoveAssignment) &&
+           "constructors and destructors always have unqualified lvalue this");
+  if (ConstArg || VolatileArg)
+    assert((SM != CXXDefaultConstructor && SM != CXXDestructor) &&
+           "parameter-less special members can't have qualified arguments");
+
+  llvm::FoldingSetNodeID ID;
+  ID.AddPointer(D);
+  ID.AddInteger(SM);
+  ID.AddInteger(ConstArg);
+  ID.AddInteger(VolatileArg);
+  ID.AddInteger(RValueThis);
+  ID.AddInteger(ConstThis);
+  ID.AddInteger(VolatileThis);
+
+  void *InsertPoint;
+  SpecialMemberOverloadResult *Result =
+    SpecialMemberCache.FindNodeOrInsertPos(ID, InsertPoint);
+
+  // This was already cached
+  if (Result)
+    return Result;
+
+  Result = new SpecialMemberOverloadResult(ID);
+  SpecialMemberCache.InsertNode(Result, InsertPoint);
+
+  if (SM == CXXDestructor) {
+    if (!D->hasDeclaredDestructor())
+      DeclareImplicitDestructor(D);
+    CXXDestructorDecl *DD = D->getDestructor();
+    assert(DD && "record without a destructor");
+    Result->setMethod(DD);
+    Result->setSuccess(DD->isDeleted());
+    Result->setConstParamMatch(false);
+    return Result;
+  }
+
+  llvm_unreachable("haven't implemented this for non-destructors yet");
+}
+
 /// \brief Look up the constructors for the given class.
 DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) {
   // If the copy constructor has not yet been declared, do so now.
@@ -2158,12 +2210,9 @@
 ///
 /// \returns The destructor for this class.
 CXXDestructorDecl *Sema::LookupDestructor(CXXRecordDecl *Class) {
-  // If the destructor has not yet been declared, do so now.
-  if (CanDeclareSpecialMemberFunction(Context, Class) &&
-      !Class->hasDeclaredDestructor())
-    DeclareImplicitDestructor(Class);
-
-  return Class->getDestructor();
+  return cast<CXXDestructorDecl>(LookupSpecialMember(Class, CXXDestructor,
+                                                     false, false, false,
+                                                     false, false)->getMethod());
 }
 
 void ADLResult::insert(NamedDecl *New) {





More information about the cfe-commits mailing list