[cfe-commits] r89575 - in /cfe/trunk/lib/Sema: Sema.h SemaExpr.cpp SemaTemplateInstantiate.cpp

John McCall rjmccall at apple.com
Sat Nov 21 17:44:31 PST 2009


Author: rjmccall
Date: Sat Nov 21 19:44:31 2009
New Revision: 89575

URL: http://llvm.org/viewvc/llvm-project?rev=89575&view=rev
Log:
Reorganize the intermediate BuildDeclarationNameExpr routines again.


Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Nov 21 19:44:31 2009
@@ -1416,9 +1416,13 @@
                                             bool HasTrailingLParen,
                                             const CXXScopeSpec *SS,
                                             bool isAddressOfOperand = false);
+  OwningExprResult BuildImplicitMemberReferenceExpr(const CXXScopeSpec *SS,
+                                                    LookupResult &R);
+  bool UseArgumentDependentLookup(const CXXScopeSpec *SS,
+                                  const LookupResult &R,
+                                  bool HasTrailingLParen);
   OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec *SS,
-                                            LookupResult &R, bool ADL,
-                                            bool isAddressOfOperand);
+                                            LookupResult &R, bool ADL);
   OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec *SS,
                                             SourceLocation Loc,
                                             DeclarationName Name,

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Nov 21 19:44:31 2009
@@ -777,8 +777,7 @@
 
   // Determine whether this name might be a candidate for
   // argument-dependent lookup.
-  bool ADL = getLangOptions().CPlusPlus && (!SS || !SS->isSet()) &&
-             HasTrailingLParen;
+  bool ADL = UseArgumentDependentLookup(SS, Lookup, HasTrailingLParen);
 
   if (Lookup.empty() && !ADL) {
     // Otherwise, this could be an implicitly declared function reference (legal
@@ -844,8 +843,31 @@
     }
   }
 
-  return BuildDeclarationNameExpr(SS, Lookup, HasTrailingLParen,
-                                  isAddressOfOperand);
+  // &SomeClass::foo is an abstract member reference, regardless of
+  // the nature of foo, but &SomeClass::foo(...) is not.  If this is
+  // *not* an abstract member reference, and any of the results is a
+  // class member (which necessarily means they're all class members),
+  // then we make an implicit member reference instead.
+  //
+  // This check considers all the same information as the "needs ADL"
+  // check, but there's no simple logical relationship other than the
+  // fact that they can never be simultaneously true.  We could
+  // calculate them both in one pass if that proves important for
+  // performance.
+  if (!ADL) {
+    bool isAbstractMemberPointer = 
+      (isAddressOfOperand && !HasTrailingLParen && SS && !SS->isEmpty());
+
+    if (!isAbstractMemberPointer && !Lookup.empty() &&
+        isa<CXXRecordDecl>((*Lookup.begin())->getDeclContext())) {
+      return BuildImplicitMemberReferenceExpr(SS, Lookup);
+    }
+  }
+
+  assert(Lookup.getResultKind() != LookupResult::FoundUnresolvedValue &&
+         "found UnresolvedUsingValueDecl in non-class scope");
+
+  return BuildDeclarationNameExpr(SS, Lookup, ADL);
 }
 
 /// \brief Cast member's object to its own class if necessary.
@@ -894,9 +916,10 @@
 /// Builds an implicit member access expression from the given
 /// unqualified lookup set, which is known to contain only class
 /// members.
-Sema::OwningExprResult BuildImplicitMemberExpr(Sema &S, LookupResult &R,
-                                               const CXXScopeSpec *SS) {
-  NamedDecl *D = R.getAsSingleDecl(S.Context);
+Sema::OwningExprResult
+Sema::BuildImplicitMemberReferenceExpr(const CXXScopeSpec *SS,
+                                       LookupResult &R) {
+  NamedDecl *D = R.getAsSingleDecl(Context);
   SourceLocation Loc = R.getNameLoc();
 
   // We may have found a field within an anonymous union or struct
@@ -904,15 +927,15 @@
   // FIXME: This needs to happen post-isImplicitMemberReference?
   if (FieldDecl *FD = dyn_cast<FieldDecl>(D))
     if (cast<RecordDecl>(FD->getDeclContext())->isAnonymousStructOrUnion())
-      return S.BuildAnonymousStructUnionMemberReference(Loc, FD);
+      return BuildAnonymousStructUnionMemberReference(Loc, FD);
 
   QualType ThisType;
   QualType MemberType;
-  if (S.isImplicitMemberReference(SS, D, Loc, ThisType, MemberType)) {
-    Expr *This = new (S.Context) CXXThisExpr(SourceLocation(), ThisType);
-    S.MarkDeclarationReferenced(Loc, D);
-    if (S.PerformObjectMemberConversion(This, D))
-      return S.ExprError();
+  if (isImplicitMemberReference(SS, D, Loc, ThisType, MemberType)) {
+    Expr *This = new (Context) CXXThisExpr(SourceLocation(), ThisType);
+    MarkDeclarationReferenced(Loc, D);
+    if (PerformObjectMemberConversion(This, D))
+      return ExprError();
 
     bool ShouldCheckUse = true;
     if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
@@ -922,46 +945,43 @@
         ShouldCheckUse = false;
     }
 
-    if (ShouldCheckUse && S.DiagnoseUseOfDecl(D, Loc))
-      return S.ExprError();
-    return S.Owned(BuildMemberExpr(S.Context, This, true, SS, D,
-                                   Loc, MemberType));
+    if (ShouldCheckUse && DiagnoseUseOfDecl(D, Loc))
+      return ExprError();
+    return Owned(BuildMemberExpr(Context, This, true, SS, D, Loc, MemberType));
   }
 
   if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
-    if (!Method->isStatic()) {
-      S.Diag(Loc, diag::err_member_call_without_object);
-      return S.ExprError();
-    }
+    if (!Method->isStatic())
+      return ExprError(Diag(Loc, diag::err_member_call_without_object));
   }
 
   if (isa<FieldDecl>(D)) {
-    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(S.CurContext)) {
+    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
       if (MD->isStatic()) {
         // "invalid use of member 'x' in static member function"
-        S.Diag(Loc,diag::err_invalid_member_use_in_static_method)
+        Diag(Loc, diag::err_invalid_member_use_in_static_method)
           << D->getDeclName();
-        return S.ExprError();
+        return ExprError();
       }
     }
 
     // Any other ways we could have found the field in a well-formed
     // program would have been turned into implicit member expressions
     // above.
-    S.Diag(Loc, diag::err_invalid_non_static_member_use)
+    Diag(Loc, diag::err_invalid_non_static_member_use)
       << D->getDeclName();
-    return S.ExprError();
+    return ExprError();
   }
 
-  return S.BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getLookupName(),
-                                    /*ADL*/ false, R.isOverloadedResult(),
-                                    R.begin(), R.end() - R.begin());
+  // We're not in an implicit member-reference context, but the lookup
+  // results might not require an instance.  Try to build a non-member
+  // decl reference.
+  return BuildDeclarationNameExpr(SS, R, /*ADL*/ false);
 }
 
-static bool UseArgumentDependentLookup(Sema &SemaRef,
-                                       const CXXScopeSpec *SS,
-                                       bool HasTrailingLParen,
-                                       const LookupResult &R) {
+bool Sema::UseArgumentDependentLookup(const CXXScopeSpec *SS,
+                                      const LookupResult &R,
+                                      bool HasTrailingLParen) {
   // Only when used directly as the postfix-expression of a call.
   if (!HasTrailingLParen)
     return false;
@@ -971,7 +991,7 @@
     return false;
 
   // Only in C++ or ObjC++.
-  if (!SemaRef.getLangOptions().CPlusPlus)
+  if (!getLangOptions().CPlusPlus)
     return false;
 
   // Turn off ADL when we find certain kinds of declarations during
@@ -1015,38 +1035,6 @@
 }
 
 
-/// \brief Complete semantic analysis for a reference to the given
-/// lookup results.
-Sema::OwningExprResult
-Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS,
-                               LookupResult &R,
-                               bool HasTrailingLParen,
-                               bool isAddressOfOperand) {
-  assert(!R.isAmbiguous() && "results are ambiguous");
-
-  // &SomeClass::foo is an abstract member reference, regardless of
-  // the nature of foo, but &SomeClass::foo(...) is not.
-  bool isAbstractMemberPointer = 
-    (isAddressOfOperand && !HasTrailingLParen && SS && !SS->isEmpty());
-
-  // If we're *not* an abstract member reference, and any of the
-  // results are class members (i.e. they're all class members), then
-  // we make an implicit member reference instead.
-  if (!isAbstractMemberPointer && !R.empty() &&
-      isa<CXXRecordDecl>((*R.begin())->getDeclContext())) {
-    return BuildImplicitMemberExpr(*this, R, SS);
-  }
-
-  assert(R.getResultKind() != LookupResult::FoundUnresolvedValue &&
-         "found UnresolvedUsingValueDecl in non-class scope");
-
-  bool ADL = UseArgumentDependentLookup(*this, SS, HasTrailingLParen, R);
-
-  return BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getLookupName(),
-                                  ADL, R.isOverloadedResult(),
-                                  R.begin(), R.end() - R.begin());
-}
-
 /// Diagnoses obvious problems with the use of the given declaration
 /// as an expression.  This is only actually called for lookups that
 /// were not overloaded, and it doesn't promise that the declaration
@@ -1072,29 +1060,28 @@
 
 Sema::OwningExprResult
 Sema::BuildDeclarationNameExpr(const CXXScopeSpec *SS,
-                               SourceLocation Loc,
-                               DeclarationName Name,
-                               bool NeedsADL,
-                               bool IsOverloaded,
-                               NamedDecl * const *Decls,
-                               unsigned NumDecls) {
-  if (!NeedsADL && !IsOverloaded)
-    return BuildDeclarationNameExpr(SS, Loc, Decls[0]->getUnderlyingDecl());
+                               LookupResult &R,
+                               bool NeedsADL) {
+  assert(R.getResultKind() != LookupResult::FoundUnresolvedValue);
+
+  if (!NeedsADL && !R.isOverloadedResult())
+    return BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getFoundDecl());
 
   // We only need to check the declaration if there's exactly one
   // result, because in the overloaded case the results can only be
   // functions and function templates.
-  if (!IsOverloaded && NumDecls == 1 &&
-      CheckDeclInExpr(*this, Loc, Decls[0]->getUnderlyingDecl()))
+  if (R.isSingleResult() &&
+      CheckDeclInExpr(*this, R.getNameLoc(), R.getFoundDecl()))
     return ExprError();
 
   UnresolvedLookupExpr *ULE
     = UnresolvedLookupExpr::Create(Context,
                     SS ? (NestedNameSpecifier *)SS->getScopeRep() : 0,
                                    SS ? SS->getRange() : SourceRange(),
-                                   Name, Loc, NeedsADL, IsOverloaded);
-  for (unsigned I = 0; I != NumDecls; ++I)
-    ULE->addDecl(Decls[I]);
+                                   R.getLookupName(), R.getNameLoc(),
+                                   NeedsADL, R.isOverloadedResult());
+  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I)
+    ULE->addDecl(*I);
 
   return Owned(ULE);
 }

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Sat Nov 21 19:44:31 2009
@@ -12,6 +12,7 @@
 
 #include "Sema.h"
 #include "TreeTransform.h"
+#include "Lookup.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Expr.h"
@@ -699,7 +700,8 @@
 Sema::OwningExprResult
 TemplateInstantiator::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
                                                     bool isAddressOfOperand) {
-  llvm::SmallVector<NamedDecl*, 16> InstDecls;
+  LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
+                 Sema::LookupOrdinaryName);
 
   for (UnresolvedLookupExpr::decls_iterator I = Old->decls_begin(),
          E = Old->decls_end(); I != E; ++I) {
@@ -715,9 +717,14 @@
     // Analogously.
     assert(!isa<UnresolvedUsingValueDecl>(InstD->getUnderlyingDecl()));
 
-    InstDecls.push_back(InstD);
+    R.addDecl(InstD);
   }
 
+  R.resolveKind();
+
+  // This shouldn't be possible.
+  assert(!R.isAmbiguous());
+
   CXXScopeSpec SS;
   NestedNameSpecifier *Qualifier = 0;
   if (Old->getQualifier()) {
@@ -730,10 +737,7 @@
     SS.setRange(Old->getQualifierRange());
   }
 
-  return SemaRef.BuildDeclarationNameExpr(&SS, Old->getNameLoc(),
-                                          Old->getName(), Old->requiresADL(),
-                                          Old->isOverloaded(),
-                                          InstDecls.data(), InstDecls.size());
+  return SemaRef.BuildDeclarationNameExpr(&SS, R, Old->requiresADL());
 }
 
 Sema::OwningExprResult





More information about the cfe-commits mailing list