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

Nick Lewycky nicholas at mxc.ca
Tue Jul 6 12:51:49 PDT 2010


Author: nicholas
Date: Tue Jul  6 14:51:49 2010
New Revision: 107690

URL: http://llvm.org/viewvc/llvm-project?rev=107690&view=rev
Log:
Fix multiple emission of the this-> fixit for each instantiation by fixing the
AST during the instantiation. Fixes PR7417!

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=107690&r1=107689&r2=107690&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Jul  6 14:51:49 2010
@@ -2793,6 +2793,7 @@
                                          const CXXMethodDecl *Old);
 
   bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange);
+
   //===--------------------------------------------------------------------===//
   // C++ Access Control
   //
@@ -3562,6 +3563,12 @@
   /// to implement it anywhere else.
   ActiveTemplateInstantiation LastTemplateInstantiationErrorContext;
 
+  /// \brief The stack of calls expression undergoing template instantiation.
+  ///
+  /// The top of this stack is used by a fixit instantiating unresolved
+  /// function calls to fix the AST to match the textual change it prints.
+  llvm::SmallVector<CallExpr *, 8> CallsUndergoingInstantiation;
+
   /// \brief A stack object to be created when performing template
   /// instantiation.
   ///

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=107690&r1=107689&r2=107690&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jul  6 14:51:49 2010
@@ -869,8 +869,8 @@
 /// Diagnose an empty lookup.
 ///
 /// \return false if new lookup candidates were found
-bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS,
-                               LookupResult &R, CorrectTypoContext CTC) {
+bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
+                               CorrectTypoContext CTC) {
   DeclarationName Name = R.getLookupName();
 
   unsigned diagnostic = diag::err_undeclared_var_use;
@@ -886,7 +886,7 @@
   // unqualified lookup.  This is useful when (for example) the
   // original lookup would not have found something because it was a
   // dependent name.
-  for (DeclContext *DC = SS.isEmpty()? CurContext : 0;
+  for (DeclContext *DC = SS.isEmpty() ? CurContext : 0;
        DC; DC = DC->getParent()) {
     if (isa<CXXRecordDecl>(DC)) {
       LookupQualifiedName(R, DC);
@@ -903,11 +903,29 @@
         // Give a code modification hint to insert 'this->'.
         // TODO: fixit for inserting 'Base<T>::' in the other cases.
         // Actually quite difficult!
-        if (isInstance)
+        if (isInstance) {
           Diag(R.getNameLoc(), diagnostic) << Name
             << FixItHint::CreateInsertion(R.getNameLoc(), "this->");
-        else
+
+          UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(
+              CallsUndergoingInstantiation.back()->getCallee());
+          CXXMethodDecl *DepMethod = cast<CXXMethodDecl>(
+              CurMethod->getInstantiatedFromMemberFunction());
+          QualType DepThisType = DepMethod->getThisType(Context);
+          CXXThisExpr *DepThis = new (Context) CXXThisExpr(R.getNameLoc(),
+                                                           DepThisType, false);
+          TemplateArgumentListInfo TList;
+          if (ULE->hasExplicitTemplateArgs())
+            ULE->copyTemplateArgumentsInto(TList);
+          CXXDependentScopeMemberExpr *DepExpr =
+              CXXDependentScopeMemberExpr::Create(
+                  Context, DepThis, DepThisType, true, SourceLocation(),
+                  ULE->getQualifier(), ULE->getQualifierRange(), NULL, Name,
+                  R.getNameLoc(), &TList);
+          CallsUndergoingInstantiation.back()->setCallee(DepExpr);
+        } else {
           Diag(R.getNameLoc(), diagnostic) << Name;
+        }
 
         // Do we really want to note all of these?
         for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I)

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=107690&r1=107689&r2=107690&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Tue Jul  6 14:51:49 2010
@@ -620,6 +620,14 @@
     QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
                                            TemplateTypeParmTypeLoc TL,
                                            QualType ObjectType);
+
+    Sema::OwningExprResult TransformCallExpr(CallExpr *CE) {
+      getSema().CallsUndergoingInstantiation.push_back(CE);
+      OwningExprResult Result =
+          TreeTransform<TemplateInstantiator>::TransformCallExpr(CE);
+      getSema().CallsUndergoingInstantiation.pop_back();
+      return move(Result);
+    }
   };
 }
 





More information about the cfe-commits mailing list