Push nested-name-specifier source location information into
UnresolvedLookupExpr and UnresolvedMemberExpr.

Also, improve the computation that checks whether the base of a member
expression (either unresolved or dependent-scoped) is implicit. The
previous check didn't cover all of the cases we use in our
representation, which threw off source-location information for these
expressions (which, in turn, caused some breakage in libclang's token
annotation). 



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126681 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index b1e6010..fb99dc9 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -174,8 +174,7 @@
 UnresolvedLookupExpr *
 UnresolvedLookupExpr::Create(ASTContext &C, 
                              CXXRecordDecl *NamingClass,
-                             NestedNameSpecifier *Qualifier,
-                             SourceRange QualifierRange,
+                             NestedNameSpecifierLoc QualifierLoc,
                              const DeclarationNameInfo &NameInfo,
                              bool ADL,
                              const TemplateArgumentListInfo &Args,
@@ -184,8 +183,7 @@
 {
   void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) + 
                          ExplicitTemplateArgumentList::sizeFor(Args));
-  return new (Mem) UnresolvedLookupExpr(C, NamingClass,
-                                        Qualifier, QualifierRange, NameInfo,
+  return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, NameInfo,
                                         ADL, /*Overload*/ true, &Args,
                                         Begin, End);
 }
@@ -204,7 +202,7 @@
 }
 
 OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, 
-                           NestedNameSpecifier *Qualifier, SourceRange QRange,
+                           NestedNameSpecifierLoc QualifierLoc,
                            const DeclarationNameInfo &NameInfo,
                            const TemplateArgumentListInfo *TemplateArgs,
                            UnresolvedSetIterator Begin, 
@@ -215,10 +213,11 @@
          KnownDependent,
          (KnownContainsUnexpandedParameterPack ||
           NameInfo.containsUnexpandedParameterPack() ||
-          (Qualifier && Qualifier->containsUnexpandedParameterPack()))),
+          (QualifierLoc && 
+           QualifierLoc.getNestedNameSpecifier()
+                                      ->containsUnexpandedParameterPack()))),
     Results(0), NumResults(End - Begin), NameInfo(NameInfo), 
-    Qualifier(Qualifier), QualifierRange(QRange), 
-    HasExplicitTemplateArgs(TemplateArgs != 0)
+    QualifierLoc(QualifierLoc), HasExplicitTemplateArgs(TemplateArgs != 0)
 {
   NumResults = End - Begin;
   if (NumResults) {
@@ -784,19 +783,59 @@
   return E;
 }
 
+/// \brief Determine whether this expression is an implicit C++ 'this'.
+static bool isImplicitThis(const Expr *E) {
+  // Strip away parentheses and casts we don't care about.
+  while (true) {
+    if (const ParenExpr *Paren = dyn_cast<ParenExpr>(E)) {
+      E = Paren->getSubExpr();
+      continue;
+    }
+    
+    if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+      if (ICE->getCastKind() == CK_NoOp ||
+          ICE->getCastKind() == CK_LValueToRValue ||
+          ICE->getCastKind() == CK_DerivedToBase || 
+          ICE->getCastKind() == CK_UncheckedDerivedToBase) {
+        E = ICE->getSubExpr();
+        continue;
+      }
+    }
+    
+    if (const UnaryOperator* UnOp = dyn_cast<UnaryOperator>(E)) {
+      if (UnOp->getOpcode() == UO_Extension) {
+        E = UnOp->getSubExpr();
+        continue;
+      }
+    }
+    
+    break;
+  }
+  
+  if (const CXXThisExpr *This = dyn_cast<CXXThisExpr>(E))
+    return This->isImplicit();
+  
+  return false;
+}
+
+bool CXXDependentScopeMemberExpr::isImplicitAccess() const {
+  if (Base == 0)
+    return true;
+  
+  return isImplicitThis(cast<Expr>(Base));
+}
+
 UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, 
                                            bool HasUnresolvedUsing,
                                            Expr *Base, QualType BaseType,
                                            bool IsArrow,
                                            SourceLocation OperatorLoc,
-                                           NestedNameSpecifier *Qualifier,
-                                           SourceRange QualifierRange,
+                                           NestedNameSpecifierLoc QualifierLoc,
                                    const DeclarationNameInfo &MemberNameInfo,
                                    const TemplateArgumentListInfo *TemplateArgs,
                                            UnresolvedSetIterator Begin, 
                                            UnresolvedSetIterator End)
-  : OverloadExpr(UnresolvedMemberExprClass, C, 
-                 Qualifier, QualifierRange, MemberNameInfo,
+  : OverloadExpr(UnresolvedMemberExprClass, C, QualifierLoc, MemberNameInfo,
                  TemplateArgs, Begin, End,
                  // Dependent
                  ((Base && Base->isTypeDependent()) ||
@@ -808,13 +847,19 @@
     Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
 }
 
+bool UnresolvedMemberExpr::isImplicitAccess() const {
+  if (Base == 0)
+    return true;
+  
+  return isImplicitThis(cast<Expr>(Base));
+}
+
 UnresolvedMemberExpr *
 UnresolvedMemberExpr::Create(ASTContext &C, 
                              bool HasUnresolvedUsing,
                              Expr *Base, QualType BaseType, bool IsArrow,
                              SourceLocation OperatorLoc,
-                             NestedNameSpecifier *Qualifier,
-                             SourceRange QualifierRange,
+                             NestedNameSpecifierLoc QualifierLoc,
                              const DeclarationNameInfo &MemberNameInfo,
                              const TemplateArgumentListInfo *TemplateArgs,
                              UnresolvedSetIterator Begin, 
@@ -826,7 +871,7 @@
   void *Mem = C.Allocate(size, llvm::alignOf<UnresolvedMemberExpr>());
   return new (Mem) UnresolvedMemberExpr(C, 
                              HasUnresolvedUsing, Base, BaseType,
-                             IsArrow, OperatorLoc, Qualifier, QualifierRange,
+                             IsArrow, OperatorLoc, QualifierLoc,
                              MemberNameInfo, TemplateArgs, Begin, End);
 }
 
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index 506d261..5b28bc3 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -642,7 +642,8 @@
     if (SrcExpr->getType() == Self.Context.OverloadTy) {
       OverloadExpr* oe = OverloadExpr::find(SrcExpr).Expression;
       Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload)
-        << oe->getName() << DestType << OpRange << oe->getQualifierRange();
+        << oe->getName() << DestType << OpRange 
+        << oe->getQualifierLoc().getSourceRange();
       Self.NoteAllOverloadCandidates(SrcExpr);
     } else {
       diagnoseBadCast(Self, msg, CT_Static, OpRange, SrcExpr, DestType);
@@ -1289,7 +1290,7 @@
     OverloadExpr* oe = OverloadExpr::find(SrcExpr).Expression;
     Self.Diag(OpRangeForComplaining.getBegin(), DiagIDForComplaining)
       << oe->getName() << DestTypeForComplaining << OpRangeForComplaining 
-              << oe->getQualifierRange();
+      << oe->getQualifierLoc().getSourceRange();
     Self.NoteAllOverloadCandidates(SrcExpr);
   }
   return SingleFunctionExpression;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 2abbcf0..6c8398e 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1351,12 +1351,8 @@
             if (ULE->hasExplicitTemplateArgs())
               ULE->copyTemplateArgumentsInto(TList);
             
-            // FIXME: We should have nested-name-specifier location info in
-            // the ULE itself.
             CXXScopeSpec SS;
-            SS.MakeTrivial(Context, ULE->getQualifier(), 
-                           ULE->getQualifierRange());
-
+            SS.Adopt(ULE->getQualifierLoc());
             CXXDependentScopeMemberExpr *DepExpr =
                 CXXDependentScopeMemberExpr::Create(
                     Context, DepThis, DepThisType, true, SourceLocation(),
@@ -2283,8 +2279,8 @@
 
   UnresolvedLookupExpr *ULE
     = UnresolvedLookupExpr::Create(Context, R.getNamingClass(),
-                                   (NestedNameSpecifier*) SS.getScopeRep(),
-                                   SS.getRange(), R.getLookupNameInfo(),
+                                   SS.getWithLocInContext(Context),
+                                   R.getLookupNameInfo(),
                                    NeedsADL, R.isOverloadedResult(),
                                    R.begin(), R.end());
 
@@ -3483,7 +3479,6 @@
   }
   R.setBaseObjectType(BaseType);
 
-  NestedNameSpecifier *Qualifier = SS.getScopeRep();
   const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo();
   DeclarationName MemberName = MemberNameInfo.getName();
   SourceLocation MemberLoc = MemberNameInfo.getLoc();
@@ -3528,7 +3523,7 @@
       = UnresolvedMemberExpr::Create(Context, R.isUnresolvableResult(),
                                      BaseExpr, BaseExprType,
                                      IsArrow, OpLoc,
-                                     Qualifier, SS.getRange(),
+                                     SS.getWithLocInContext(Context),
                                      MemberNameInfo,
                                      TemplateArgs, R.begin(), R.end());
 
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 8d03285..8893ab4 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -7590,9 +7590,7 @@
                       SourceLocation RParenLoc) {
 
   CXXScopeSpec SS;
-  if (ULE->getQualifier())
-    SS.MakeTrivial(SemaRef.Context, 
-                   ULE->getQualifier(), ULE->getQualifierRange());
+  SS.Adopt(ULE->getQualifierLoc());
 
   TemplateArgumentListInfo TABuffer;
   const TemplateArgumentListInfo *ExplicitTemplateArgs = 0;
@@ -7776,11 +7774,11 @@
     CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
     UnresolvedLookupExpr *Fn
       = UnresolvedLookupExpr::Create(Context, NamingClass,
-                                     0, SourceRange(), OpNameInfo,
+                                     NestedNameSpecifierLoc(), OpNameInfo,
                                      /*ADL*/ true, IsOverloaded(Fns),
                                      Fns.begin(), Fns.end());
     return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
-                                                   &Args[0], NumArgs,
+                                                  &Args[0], NumArgs,
                                                    Context.DependentTy,
                                                    VK_RValue,
                                                    OpLoc));
@@ -7956,8 +7954,9 @@
     // TODO: provide better source location info in DNLoc component.
     DeclarationNameInfo OpNameInfo(OpName, OpLoc);
     UnresolvedLookupExpr *Fn
-      = UnresolvedLookupExpr::Create(Context, NamingClass, 0, SourceRange(),
-                                     OpNameInfo, /*ADL*/ true, IsOverloaded(Fns),
+      = UnresolvedLookupExpr::Create(Context, NamingClass, 
+                                     NestedNameSpecifierLoc(), OpNameInfo, 
+                                     /*ADL*/ true, IsOverloaded(Fns),
                                      Fns.begin(), Fns.end());
     return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
                                                    Args, 2,
@@ -8187,7 +8186,7 @@
     OpNameInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc));
     UnresolvedLookupExpr *Fn
       = UnresolvedLookupExpr::Create(Context, NamingClass,
-                                     0, SourceRange(), OpNameInfo,
+                                     NestedNameSpecifierLoc(), OpNameInfo,
                                      /*ADL*/ true, /*Overloaded*/ false,
                                      UnresolvedSetIterator(),
                                      UnresolvedSetIterator());
@@ -8929,9 +8928,10 @@
       TemplateArgs = &TemplateArgsBuffer;
     }
 
+    // FIXME: Nested-name-specifier source location information for DeclRefExpr.
     return DeclRefExpr::Create(Context,
                                ULE->getQualifier(),
-                               ULE->getQualifierRange(),
+                               ULE->getQualifierLoc().getSourceRange(),
                                Fn,
                                ULE->getNameLoc(),
                                Fn->getType(),
@@ -8952,10 +8952,11 @@
     // If we're filling in a static method where we used to have an
     // implicit member access, rewrite to a simple decl ref.
     if (MemExpr->isImplicitAccess()) {
+      // FIXME: Source location information for DeclRefExpr
       if (cast<CXXMethodDecl>(Fn)->isStatic()) {
         return DeclRefExpr::Create(Context,
                                    MemExpr->getQualifier(),
-                                   MemExpr->getQualifierRange(),
+                                   MemExpr->getQualifierLoc().getSourceRange(),
                                    Fn,
                                    MemExpr->getMemberLoc(),
                                    Fn->getType(),
@@ -8964,7 +8965,7 @@
       } else {
         SourceLocation Loc = MemExpr->getMemberLoc();
         if (MemExpr->getQualifier())
-          Loc = MemExpr->getQualifierRange().getBegin();
+          Loc = MemExpr->getQualifierLoc().getBeginLoc();
         Base = new (Context) CXXThisExpr(Loc,
                                          MemExpr->getBaseType(),
                                          /*isImplicit=*/true);
@@ -8972,10 +8973,11 @@
     } else
       Base = MemExpr->getBase();
 
+    // FIXME: Source location information for MemberExpr
     return MemberExpr::Create(Context, Base,
                               MemExpr->isArrow(),
                               MemExpr->getQualifier(),
-                              MemExpr->getQualifierRange(),
+                              MemExpr->getQualifierLoc().getSourceRange(),
                               Fn,
                               Found,
                               MemExpr->getMemberNameInfo(),
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 0185035..1c776fb 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1832,8 +1832,8 @@
 }
 
 ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
-                                                 LookupResult &R,
-                                                 bool RequiresADL,
+                                     LookupResult &R,
+                                     bool RequiresADL,
                                  const TemplateArgumentListInfo &TemplateArgs) {
   // FIXME: Can we do any checking at this point? I guess we could check the
   // template arguments that we have against the template name, if the template
@@ -1849,19 +1849,12 @@
   assert(!R.empty() && "empty lookup results when building templateid");
   assert(!R.isAmbiguous() && "ambiguous lookup when building templateid");
 
-  NestedNameSpecifier *Qualifier = 0;
-  SourceRange QualifierRange;
-  if (SS.isSet()) {
-    Qualifier = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
-    QualifierRange = SS.getRange();
-  }
-
   // We don't want lookup warnings at this point.
   R.suppressDiagnostics();
 
   UnresolvedLookupExpr *ULE
     = UnresolvedLookupExpr::Create(Context, R.getNamingClass(),
-                                   Qualifier, QualifierRange,
+                                   SS.getWithLocInContext(Context),
                                    R.getLookupNameInfo(),
                                    RequiresADL, TemplateArgs,
                                    R.begin(), R.end());
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 4e29026..6514b2e 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -2000,13 +2000,12 @@
                                                QualType BaseType,
                                                SourceLocation OperatorLoc,
                                                bool IsArrow,
-                                               NestedNameSpecifier *Qualifier,
-                                               SourceRange QualifierRange,
+                                           NestedNameSpecifierLoc QualifierLoc,
                                                NamedDecl *FirstQualifierInScope,
                                                LookupResult &R,
                                 const TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
-    SS.MakeTrivial(SemaRef.Context, Qualifier, QualifierRange);
+    SS.Adopt(QualifierLoc);
 
     return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
                                             OperatorLoc, IsArrow,
@@ -6779,14 +6778,13 @@
 
   // Rebuild the nested-name qualifier, if present.
   CXXScopeSpec SS;
-  NestedNameSpecifier *Qualifier = 0;
-  if (Old->getQualifier()) {
-    Qualifier = getDerived().TransformNestedNameSpecifier(Old->getQualifier(),
-                                                    Old->getQualifierRange());
-    if (!Qualifier)
+  if (Old->getQualifierLoc()) {
+    NestedNameSpecifierLoc QualifierLoc
+      = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
+    if (!QualifierLoc)
       return ExprError();
     
-    SS.MakeTrivial(SemaRef.Context, Qualifier, Old->getQualifierRange());
+    SS.Adopt(QualifierLoc);
   } 
   
   if (Old->getNamingClass()) {
@@ -7139,12 +7137,11 @@
     BaseType = getDerived().TransformType(Old->getBaseType());
   }
 
-  NestedNameSpecifier *Qualifier = 0;
-  if (Old->getQualifier()) {
-    Qualifier
-      = getDerived().TransformNestedNameSpecifier(Old->getQualifier(),
-                                                  Old->getQualifierRange());
-    if (Qualifier == 0)
+  NestedNameSpecifierLoc QualifierLoc;
+  if (Old->getQualifierLoc()) {
+    QualifierLoc
+    = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
+    if (!QualifierLoc)
       return ExprError();
   }
 
@@ -7212,8 +7209,7 @@
                                                   BaseType,
                                                   Old->getOperatorLoc(),
                                                   Old->isArrow(),
-                                                  Qualifier,
-                                                  Old->getQualifierRange(),
+                                                  QualifierLoc,
                                                   FirstQualifierInScope,
                                                   R,
                                               (Old->hasExplicitTemplateArgs()
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 24ff7e8..86e9cdc 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1253,24 +1253,23 @@
   E->initializeResults(*Reader.getContext(), Decls.begin(), Decls.end());
 
   ReadDeclarationNameInfo(E->NameInfo, Record, Idx);
-  E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx));
-  E->setQualifierRange(ReadSourceRange(Record, Idx));
+  E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
 }
 
 void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
   VisitOverloadExpr(E);
-  E->setArrow(Record[Idx++]);
-  E->setHasUnresolvedUsing(Record[Idx++]);
-  E->setBase(Reader.ReadSubExpr());
-  E->setBaseType(Reader.GetType(Record[Idx++]));
-  E->setOperatorLoc(ReadSourceLocation(Record, Idx));
+  E->IsArrow = Record[Idx++];
+  E->HasUnresolvedUsing = Record[Idx++];
+  E->Base = Reader.ReadSubExpr();
+  E->BaseType = Reader.GetType(Record[Idx++]);
+  E->OperatorLoc = ReadSourceLocation(Record, Idx);
 }
 
 void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
   VisitOverloadExpr(E);
-  E->setRequiresADL(Record[Idx++]);
-  E->setOverloaded(Record[Idx++]);
-  E->setNamingClass(cast_or_null<CXXRecordDecl>(Reader.GetDecl(Record[Idx++])));
+  E->RequiresADL = Record[Idx++];
+  E->Overloaded = Record[Idx++];
+  E->NamingClass = cast_or_null<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]));
 }
 
 void ASTStmtReader::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 6e81ebb..da194d3 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -1252,8 +1252,7 @@
   }
 
   Writer.AddDeclarationNameInfo(E->NameInfo, Record);
-  Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
-  Writer.AddSourceRange(E->getQualifierRange(), Record);
+  Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
 }
 
 void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {