Implement caching of default constructors on the resolution table. This
isn't yet used for the less controlled environments of initialization.

Also a few random text fixups.

llvm-svn: 132833
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index f7726d9..b730408 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -2186,12 +2186,133 @@
     return Result;
   }
 
-  llvm_unreachable("haven't implemented this for non-destructors yet");
+  // Prepare for overload resolution. Here we construct a synthetic argument
+  // if necessary and make sure that implicit functions are declared.
+  CanQualType CanTy = Context.getCanonicalType(Context.getTagDeclType(D));
+  DeclarationName Name;
+  Expr *Arg = 0;
+  unsigned NumArgs;
+
+  if (SM == CXXDefaultConstructor) {
+    Name = Context.DeclarationNames.getCXXConstructorName(CanTy);
+    NumArgs = 0;
+    if (D->needsImplicitDefaultConstructor())
+      DeclareImplicitDefaultConstructor(D);
+  } else {
+    if (SM == CXXCopyConstructor || SM == CXXMoveConstructor) {
+      Name = Context.DeclarationNames.getCXXConstructorName(CanTy);
+      if (!D->hasDeclaredCopyConstructor())
+        DeclareImplicitCopyConstructor(D);
+      // TODO: Move constructors
+    } else {
+      Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal);
+      if (!D->hasDeclaredCopyAssignment())
+        DeclareImplicitCopyAssignment(D);
+      // TODO: Move assignment
+    }
+
+    QualType ArgType = CanTy;
+    if (ConstArg)
+      ArgType.addConst();
+    if (VolatileArg)
+      ArgType.addVolatile();
+
+    // This isn't /really/ specified by the standard, but it's implied
+    // we should be working from an RValue in the case of move to ensure
+    // that we prefer to bind to rvalue references, and an LValue in the
+    // case of copy to ensure we don't bind to rvalue references.
+    // Possibly an XValue is actually correct in the case of move, but
+    // there is no semantic difference for class types in this restricted
+    // case.
+    ExprValueKind VK;
+    if (SM == CXXCopyAssignment || SM == CXXMoveAssignment)
+      VK = VK_LValue;
+    else
+      VK = VK_RValue;
+
+    NumArgs = 1;
+    Arg = new (Context) OpaqueValueExpr(SourceLocation(), ArgType, VK);
+  }
+
+  // Create the object argument
+  QualType ThisTy = CanTy;
+  if (ConstThis)
+    ThisTy.addConst();
+  if (VolatileThis)
+    ThisTy.addVolatile();
+  Expr::Classification ObjectClassification =
+    (new (Context) OpaqueValueExpr(SourceLocation(), ThisTy,
+                                   RValueThis ? VK_RValue : VK_LValue))->
+        Classify(Context);
+
+  // Now we perform lookup on the name we computed earlier and do overload
+  // resolution. Lookup is only performed directly into the class since there
+  // will always be a (possibly implicit) declaration to shadow any others.
+  OverloadCandidateSet OCS((SourceLocation()));
+  DeclContext::lookup_iterator I, E;
+  Result->setConstParamMatch(false);
+
+  llvm::tie(I, E) = D->lookup(Name);
+  assert((I != E) &&
+         "lookup for a constructor or assignment operator was empty");
+  for ( ; I != E; ++I) {
+    if ((*I)->isInvalidDecl())
+      continue;
+
+    if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(*I)) {
+      AddOverloadCandidate(M, DeclAccessPair::make(M, AS_public), &Arg, NumArgs,
+                           OCS, true);
+
+      // Here we're looking for a const parameter to speed up creation of
+      // implicit copy methods.
+      if ((SM == CXXCopyAssignment && M->isCopyAssignmentOperator()) ||
+          (SM == CXXCopyConstructor &&
+            cast<CXXConstructorDecl>(M)->isCopyConstructor())) {
+        QualType ArgType = M->getType()->getAs<FunctionProtoType>()->getArgType(0);
+        if (ArgType->getPointeeType().isConstQualified())
+          Result->setConstParamMatch(true);
+      }
+    } else {
+      FunctionTemplateDecl *Tmpl = cast<FunctionTemplateDecl>(*I);
+      AddTemplateOverloadCandidate(Tmpl, DeclAccessPair::make(Tmpl, AS_public),
+                                   0, &Arg, NumArgs, OCS, true);
+    }
+  }
+
+  OverloadCandidateSet::iterator Best;
+  switch (OCS.BestViableFunction(*this, SourceLocation(), Best)) {
+    case OR_Success:
+      Result->setMethod(cast<CXXMethodDecl>(Best->Function));
+      Result->setSuccess(true);
+      break;
+
+    case OR_Deleted:
+      Result->setMethod(cast<CXXMethodDecl>(Best->Function));
+      Result->setSuccess(false);
+      break;
+
+    case OR_Ambiguous:
+    case OR_No_Viable_Function:
+      Result->setMethod(0);
+      Result->setSuccess(false);
+      break;
+  }
+
+  return Result;
+}
+
+/// \brief Look up the default constructor for the given class.
+CXXConstructorDecl *Sema::LookupDefaultConstructor(CXXRecordDecl *Class) {
+  SpecialMemberOverloadResult *Result = 
+    LookupSpecialMember(Class, CXXDefaultConstructor, false, false, false,
+                        false, false);
+
+  return cast_or_null<CXXConstructorDecl>(Result->getMethod());
 }
 
 /// \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.
+  // If the implicit constructors have not yet been declared, do so now.
   if (CanDeclareSpecialMemberFunction(Context, Class)) {
     if (Class->needsImplicitDefaultConstructor())
       DeclareImplicitDefaultConstructor(Class);