diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 40 | 
1 files changed, 26 insertions, 14 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 0c8d4f65f09..c710b5bdad0 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1084,24 +1084,28 @@ void CodeGenModule::EmitDeferred() {    // previously unused static decl may become used during the generation of code    // for a static function, iterate until no changes are made. -  while (true) { -    if (!DeferredVTables.empty()) { -      EmitDeferredVTables(); - -      // Emitting a v-table doesn't directly cause more v-tables to -      // become deferred, although it can cause functions to be -      // emitted that then need those v-tables. -      assert(DeferredVTables.empty()); -    } +  if (!DeferredVTables.empty()) { +    EmitDeferredVTables(); -    // Stop if we're out of both deferred v-tables and deferred declarations. -    if (DeferredDeclsToEmit.empty()) -      break; +    // Emitting a v-table doesn't directly cause more v-tables to +    // become deferred, although it can cause functions to be +    // emitted that then need those v-tables. +    assert(DeferredVTables.empty()); +  } + +  // Stop if we're out of both deferred v-tables and deferred declarations. +  if (DeferredDeclsToEmit.empty()) +    return; + +  // Grab the list of decls to emit. If EmitGlobalDefinition schedules more +  // work, it will not interfere with this. +  std::vector<DeferredGlobal> CurDeclsToEmit; +  CurDeclsToEmit.swap(DeferredDeclsToEmit); -    DeferredGlobal &G = DeferredDeclsToEmit.back(); +  for (DeferredGlobal &G : CurDeclsToEmit) {      GlobalDecl D = G.GD;      llvm::GlobalValue *GV = G.GV; -    DeferredDeclsToEmit.pop_back(); +    G.GV = nullptr;      assert(!GV || GV == GetGlobalValue(getMangledName(D)));      if (!GV) @@ -1118,6 +1122,14 @@ void CodeGenModule::EmitDeferred() {      // Otherwise, emit the definition and move on to the next one.      EmitGlobalDefinition(D, GV); + +    // If we found out that we need to emit more decls, do that recursively. +    // This has the advantage that the decls are emitted in a DFS and related +    // ones are close together, which is convenient for testing. +    if (!DeferredVTables.empty() || !DeferredDeclsToEmit.empty()) { +      EmitDeferred(); +      assert(DeferredVTables.empty() && DeferredDeclsToEmit.empty()); +    }    }  }  | 

