}
}
+void CodeGenModule::clear() {
+ DeferredDeclsToEmit.clear();
+}
+
void CodeGenModule::Release() {
EmitDeferred();
applyReplacements();
// Stop if we're out of both deferred v-tables and deferred declarations.
if (DeferredDeclsToEmit.empty()) break;
- GlobalDecl D = DeferredDeclsToEmit.back();
+ DeferredGlobal &G = DeferredDeclsToEmit.back();
+ GlobalDecl D = G.GD;
+ llvm::GlobalValue *GV = G.GV;
DeferredDeclsToEmit.pop_back();
+ assert(GV == GetGlobalValue(getMangledName(D)));
// Check to see if we've already emitted this. This is necessary
// for a couple of reasons: first, decls can end up in the
// deferred-decls queue multiple times, and second, decls can end
// up with definitions in unusual ways (e.g. by an extern inline
// function acquiring a strong function redefinition). Just
// ignore these cases.
- //
- // TODO: That said, looking this up multiple times is very wasteful.
- StringRef Name = getMangledName(D);
- llvm::GlobalValue *CGRef = GetGlobalValue(Name);
- assert(CGRef && "Deferred decl wasn't referenced?");
-
- if (!CGRef->isDeclaration())
+ if(!GV->isDeclaration())
continue;
// Otherwise, emit the definition and move on to the next one.
// If the value has already been used, add it directly to the
// DeferredDeclsToEmit list.
StringRef MangledName = getMangledName(GD);
- if (GetGlobalValue(MangledName))
- DeferredDeclsToEmit.push_back(GD);
+ if (llvm::GlobalValue *GV = GetGlobalValue(MangledName))
+ addDeferredDeclToEmit(GV, GD);
else {
// Otherwise, remember that we saw a deferred decl with this name. The
// first use of the mangled name will cause it to move into
if (D && isa<CXXDestructorDecl>(D) &&
getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D),
GD.getDtorType()))
- DeferredDeclsToEmit.push_back(GD);
+ addDeferredDeclToEmit(F, GD);
// This is the first use or definition of a mangled name. If there is a
// deferred decl with this name, remember that we need to emit it at the end
// Move the potentially referenced deferred decl to the
// DeferredDeclsToEmit list, and remove it from DeferredDecls (since we
// don't need it anymore).
- DeferredDeclsToEmit.push_back(DDI->second);
+ addDeferredDeclToEmit(F, DDI->second);
DeferredDecls.erase(DDI);
// Otherwise, if this is a sized deallocation function, emit a weak
// for it at the end of the translation unit.
} else if (D && cast<FunctionDecl>(D)
->getCorrespondingUnsizedGlobalDeallocationFunction()) {
- DeferredDeclsToEmit.push_back(GD);
+ addDeferredDeclToEmit(F, GD);
// Otherwise, there are cases we have to worry about where we're
// using a declaration for which we must emit a definition but where
if (FD->isImplicit() && !ForVTable) {
assert(FD->isUsed() &&
"Sema didn't mark implicit function as used!");
- DeferredDeclsToEmit.push_back(GD.getWithDecl(FD));
+ addDeferredDeclToEmit(F, GD.getWithDecl(FD));
break;
} else if (FD->doesThisDeclarationHaveABody()) {
- DeferredDeclsToEmit.push_back(GD.getWithDecl(FD));
+ addDeferredDeclToEmit(F, GD.getWithDecl(FD));
break;
}
}
return llvm::ConstantExpr::getBitCast(Entry, Ty);
}
+ unsigned AddrSpace = GetGlobalVarAddressSpace(D, Ty->getAddressSpace());
+ llvm::GlobalVariable *GV =
+ new llvm::GlobalVariable(getModule(), Ty->getElementType(), false,
+ llvm::GlobalValue::ExternalLinkage,
+ 0, MangledName, 0,
+ llvm::GlobalVariable::NotThreadLocal, AddrSpace);
+
// This is the first use or definition of a mangled name. If there is a
// deferred decl with this name, remember that we need to emit it at the end
// of the file.
if (DDI != DeferredDecls.end()) {
// Move the potentially referenced deferred decl to the DeferredDeclsToEmit
// list, and remove it from DeferredDecls (since we don't need it anymore).
- DeferredDeclsToEmit.push_back(DDI->second);
+ addDeferredDeclToEmit(GV, DDI->second);
DeferredDecls.erase(DDI);
}
- unsigned AddrSpace = GetGlobalVarAddressSpace(D, Ty->getAddressSpace());
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(getModule(), Ty->getElementType(), false,
- llvm::GlobalValue::ExternalLinkage,
- 0, MangledName, 0,
- llvm::GlobalVariable::NotThreadLocal, AddrSpace);
-
// Handle things which are present even on external declarations.
if (D) {
// FIXME: This code is overly simple and should be merged with other global