diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/Sema.cpp | 38 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 11 | 
2 files changed, 28 insertions, 21 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index ec7b61d32a3..e9791a0e644 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -284,26 +284,24 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {  void Sema::ActOnEndOfTranslationUnit() {    // At PCH writing, implicit instantiations and VTable handling info are    // stored and performed when the PCH is included. -  if (CompleteTranslationUnit) -    while (1) { -      // C++: Perform implicit template instantiations. -      // -      // FIXME: When we perform these implicit instantiations, we do not -      // carefully keep track of the point of instantiation (C++ [temp.point]). -      // This means that name lookup that occurs within the template -      // instantiation will always happen at the end of the translation unit, -      // so it will find some names that should not be found. Although this is -      // common behavior for C++ compilers, it is technically wrong. In the -      // future, we either need to be able to filter the results of name lookup -      // or we need to perform template instantiations earlier. -      PerformPendingInstantiations(); - -      /// If DefinedUsedVTables ends up marking any virtual member -      /// functions it might lead to more pending template -      /// instantiations, which is why we need to loop here. -      if (!DefineUsedVTables()) -        break; -    } +  if (CompleteTranslationUnit) { +    // If DefinedUsedVTables ends up marking any virtual member functions it +    // might lead to more pending template instantiations, which we then need +    // to instantiate. +    DefineUsedVTables(); + +    // C++: Perform implicit template instantiations. +    // +    // FIXME: When we perform these implicit instantiations, we do not +    // carefully keep track of the point of instantiation (C++ [temp.point]). +    // This means that name lookup that occurs within the template +    // instantiation will always happen at the end of the translation unit, +    // so it will find some names that should not be found. Although this is +    // common behavior for C++ compilers, it is technically wrong. In the +    // future, we either need to be able to filter the results of name lookup +    // or we need to perform template instantiations earlier. +    PerformPendingInstantiations(); +  }    // Remove file scoped decls that turned out to be used.    UnusedFileScopedDecls.erase(std::remove_if(UnusedFileScopedDecls.begin(), diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index fc298c10e46..9899a852d01 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2108,9 +2108,12 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,    // If we're performing recursive template instantiation, create our own    // queue of pending implicit instantiations that we will instantiate later,    // while we're still within our own instantiation context. +  llvm::SmallVector<VTableUse, 16> SavedVTableUses;    std::deque<PendingImplicitInstantiation> SavedPendingInstantiations; -  if (Recursive) +  if (Recursive) { +    VTableUses.swap(SavedVTableUses);      PendingInstantiations.swap(SavedPendingInstantiations); +  }    EnterExpressionEvaluationContext EvalContext(*this,                                                  Sema::PotentiallyEvaluated); @@ -2173,10 +2176,16 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,    Scope.Exit();    if (Recursive) { +    // Define any pending vtables. +    DefineUsedVTables(); +      // Instantiate any pending implicit instantiations found during the      // instantiation of this template.      PerformPendingInstantiations(); +    // Restore the set of pending vtables. +    VTableUses.swap(SavedVTableUses); +      // Restore the set of pending implicit instantiations.      PendingInstantiations.swap(SavedPendingInstantiations);    }  | 

