aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--lib/CodeGen/CodeGenModule.cpp846
1 files changed, 500 insertions, 346 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index d88a37a45b23..36ad7f514ec8 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -39,8 +39,10 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CompileOptions &compileOpts,
Diagnostic &diags)
: BlockModule(C, M, TD, Types, *this), Context(C),
Features(C.getLangOptions()), CompileOpts(compileOpts), TheModule(M),
- TheTargetData(TD), Diags(diags), Types(C, M, TD), Runtime(0),
- MemCpyFn(0), MemMoveFn(0), MemSetFn(0), CFConstantStringClassRef(0) {
+ TheTargetData(TD), Diags(diags), Types(C, M, TD), MangleCtx(C),
+ VtableInfo(*this), Runtime(0),
+ MemCpyFn(0), MemMoveFn(0), MemSetFn(0), CFConstantStringClassRef(0),
+ VMContext(M.getContext()) {
if (!Features.ObjC1)
Runtime = 0;
@@ -61,6 +63,9 @@ CodeGenModule::~CodeGenModule() {
}
void CodeGenModule::Release() {
+ // We need to call this first because it can add deferred declarations.
+ EmitCXXGlobalInitFunc();
+
EmitDeferred();
if (Runtime)
if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction())
@@ -77,7 +82,7 @@ void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type,
bool OmitOnError) {
if (OmitOnError && getDiags().hasErrorOccurred())
return;
- unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error,
+ unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error,
"cannot compile this %0 yet");
std::string Msg = Type;
getDiags().Report(Context.getFullLoc(S->getLocStart()), DiagID)
@@ -90,13 +95,13 @@ void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type,
bool OmitOnError) {
if (OmitOnError && getDiags().hasErrorOccurred())
return;
- unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error,
+ unsigned DiagID = getDiags().getCustomDiagID(Diagnostic::Error,
"cannot compile this %0 yet");
std::string Msg = Type;
getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID) << Msg;
}
-LangOptions::VisibilityMode
+LangOptions::VisibilityMode
CodeGenModule::getDeclVisibilityMode(const Decl *D) const {
if (const VarDecl *VD = dyn_cast<VarDecl>(D))
if (VD->getStorageClass() == VarDecl::PrivateExtern)
@@ -105,7 +110,7 @@ CodeGenModule::getDeclVisibilityMode(const Decl *D) const {
if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>()) {
switch (attr->getVisibility()) {
default: assert(0 && "Unknown visibility!");
- case VisibilityAttr::DefaultVisibility:
+ case VisibilityAttr::DefaultVisibility:
return LangOptions::Default;
case VisibilityAttr::HiddenVisibility:
return LangOptions::Hidden;
@@ -117,7 +122,7 @@ CodeGenModule::getDeclVisibilityMode(const Decl *D) const {
return getLangOptions().getVisibilityMode();
}
-void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
+void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
const Decl *D) const {
// Internal definitions always have default visibility.
if (GV->hasLocalLinkage()) {
@@ -137,13 +142,13 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
}
const char *CodeGenModule::getMangledName(const GlobalDecl &GD) {
- const NamedDecl *ND = GD.getDecl();
-
+ const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
+
if (const CXXConstructorDecl *D = dyn_cast<CXXConstructorDecl>(ND))
return getMangledCXXCtorName(D, GD.getCtorType());
if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))
return getMangledCXXDtorName(D, GD.getDtorType());
-
+
return getMangledName(ND);
}
@@ -159,10 +164,10 @@ const char *CodeGenModule::getMangledName(const NamedDecl *ND) {
assert(ND->getIdentifier() && "Attempt to mangle unnamed decl.");
return ND->getNameAsCString();
}
-
+
llvm::SmallString<256> Name;
llvm::raw_svector_ostream Out(Name);
- if (!mangleName(ND, Context, Out)) {
+ if (!mangleName(getMangleContext(), ND, Out)) {
assert(ND->getIdentifier() && "Attempt to mangle unnamed decl.");
return ND->getNameAsCString();
}
@@ -174,7 +179,7 @@ const char *CodeGenModule::getMangledName(const NamedDecl *ND) {
const char *CodeGenModule::UniqueMangledName(const char *NameStart,
const char *NameEnd) {
assert(*(NameEnd - 1) == '\0' && "Mangled name must be null terminated!");
-
+
return MangledNames.GetOrCreateValue(NameStart, NameEnd).getKeyData();
}
@@ -195,32 +200,32 @@ void CodeGenModule::AddGlobalDtor(llvm::Function * Dtor, int Priority) {
void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) {
// Ctor function type is void()*.
llvm::FunctionType* CtorFTy =
- llvm::FunctionType::get(llvm::Type::VoidTy,
+ llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
std::vector<const llvm::Type*>(),
false);
llvm::Type *CtorPFTy = llvm::PointerType::getUnqual(CtorFTy);
// Get the type of a ctor entry, { i32, void ()* }.
- llvm::StructType* CtorStructTy =
- llvm::StructType::get(llvm::Type::Int32Ty,
+ llvm::StructType* CtorStructTy =
+ llvm::StructType::get(VMContext, llvm::Type::getInt32Ty(VMContext),
llvm::PointerType::getUnqual(CtorFTy), NULL);
// Construct the constructor and destructor arrays.
std::vector<llvm::Constant*> Ctors;
for (CtorList::const_iterator I = Fns.begin(), E = Fns.end(); I != E; ++I) {
std::vector<llvm::Constant*> S;
- S.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, I->second, false));
+ S.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+ I->second, false));
S.push_back(llvm::ConstantExpr::getBitCast(I->first, CtorPFTy));
Ctors.push_back(llvm::ConstantStruct::get(CtorStructTy, S));
}
if (!Ctors.empty()) {
llvm::ArrayType *AT = llvm::ArrayType::get(CtorStructTy, Ctors.size());
- new llvm::GlobalVariable(AT, false,
+ new llvm::GlobalVariable(TheModule, AT, false,
llvm::GlobalValue::AppendingLinkage,
llvm::ConstantArray::get(AT, Ctors),
- GlobalName,
- &TheModule);
+ GlobalName);
}
}
@@ -233,67 +238,56 @@ void CodeGenModule::EmitAnnotations() {
llvm::ConstantArray::get(llvm::ArrayType::get(Annotations[0]->getType(),
Annotations.size()),
Annotations);
- llvm::GlobalValue *gv =
- new llvm::GlobalVariable(Array->getType(), false,
- llvm::GlobalValue::AppendingLinkage, Array,
- "llvm.global.annotations", &TheModule);
+ llvm::GlobalValue *gv =
+ new llvm::GlobalVariable(TheModule, Array->getType(), false,
+ llvm::GlobalValue::AppendingLinkage, Array,
+ "llvm.global.annotations");
gv->setSection("llvm.metadata");
}
static CodeGenModule::GVALinkage
-GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD,
+GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD,
const LangOptions &Features) {
+ // Everything located semantically within an anonymous namespace is
+ // always internal.
+ if (FD->isInAnonymousNamespace())
+ return CodeGenModule::GVA_Internal;
+
// The kind of external linkage this function will have, if it is not
// inline or static.
CodeGenModule::GVALinkage External = CodeGenModule::GVA_StrongExternal;
if (Context.getLangOptions().CPlusPlus &&
- (FD->getPrimaryTemplate() || FD->getInstantiatedFromMemberFunction()) &&
- !FD->isExplicitSpecialization())
+ FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
External = CodeGenModule::GVA_TemplateInstantiation;
-
+
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
// C++ member functions defined inside the class are always inline.
if (MD->isInline() || !MD->isOutOfLine())
return CodeGenModule::GVA_CXXInline;
-
+
return External;
}
-
+
// "static" functions get internal linkage.
if (FD->getStorageClass() == FunctionDecl::Static)
return CodeGenModule::GVA_Internal;
if (!FD->isInline())
return External;
-
- // If the inline function explicitly has the GNU inline attribute on it, or if
- // this is C89 mode, we use to GNU semantics.
- if (!Features.C99 && !Features.CPlusPlus) {
- // extern inline in GNU mode is like C99 inline.
- if (FD->getStorageClass() == FunctionDecl::Extern)
- return CodeGenModule::GVA_C99Inline;
- // Normal inline is a strong symbol.
- return CodeGenModule::GVA_StrongExternal;
- } else if (FD->hasActiveGNUInlineAttribute(Context)) {
- // GCC in C99 mode seems to use a different decision-making
- // process for extern inline, which factors in previous
- // declarations.
- if (FD->isExternGNUInline(Context))
- return CodeGenModule::GVA_C99Inline;
- // Normal inline is a strong symbol.
- return External;
- }
- // The definition of inline changes based on the language. Note that we
- // have already handled "static inline" above, with the GVA_Internal case.
- if (Features.CPlusPlus) // inline and extern inline.
- return CodeGenModule::GVA_CXXInline;
-
- assert(Features.C99 && "Must be in C99 mode if not in C89 or C++ mode");
- if (FD->isC99InlineDefinition())
+ if (!Features.CPlusPlus || FD->hasAttr<GNUInlineAttr>()) {
+ // GNU or C99 inline semantics. Determine whether this symbol should be
+ // externally visible.
+ if (FD->isInlineDefinitionExternallyVisible())
+ return External;
+
+ // C99 inline semantics, where the symbol is not externally visible.
return CodeGenModule::GVA_C99Inline;
+ }
- return CodeGenModule::GVA_StrongExternal;
+ // C++ inline semantics
+ assert(Features.CPlusPlus && "Must be in C++ mode");
+ return CodeGenModule::GVA_CXXInline;
}
/// SetFunctionDefinitionAttributes - Set attributes for a global.
@@ -332,35 +326,35 @@ void CodeGenModule::SetFunctionDefinitionAttributes(const FunctionDecl *D,
}
void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D,
- const CGFunctionInfo &Info,
+ const CGFunctionInfo &Info,
llvm::Function *F) {
+ unsigned CallingConv;
AttributeListType AttributeList;
- ConstructAttributeList(Info, D, AttributeList);
-
+ ConstructAttributeList(Info, D, AttributeList, CallingConv);
F->setAttributes(llvm::AttrListPtr::get(AttributeList.begin(),
- AttributeList.size()));
-
- // Set the appropriate calling convention for the Function.
- if (D->hasAttr<FastCallAttr>())
- F->setCallingConv(llvm::CallingConv::X86_FastCall);
-
- if (D->hasAttr<StdCallAttr>())
- F->setCallingConv(llvm::CallingConv::X86_StdCall);
+ AttributeList.size()));
+ F->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
}
void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
llvm::Function *F) {
if (!Features.Exceptions && !Features.ObjCNonFragileABI)
- F->addFnAttr(llvm::Attribute::NoUnwind);
+ F->addFnAttr(llvm::Attribute::NoUnwind);
if (D->hasAttr<AlwaysInlineAttr>())
F->addFnAttr(llvm::Attribute::AlwaysInline);
-
- if (D->hasAttr<NoinlineAttr>())
+
+ if (D->hasAttr<NoInlineAttr>())
F->addFnAttr(llvm::Attribute::NoInline);
+
+ if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+ F->setAlignment(AA->getAlignment()/8);
+ // C++ ABI requires 2-byte alignment for member functions.
+ if (F->getAlignment() < 2 && isa<CXXMethodDecl>(D))
+ F->setAlignment(2);
}
-void CodeGenModule::SetCommonAttributes(const Decl *D,
+void CodeGenModule::SetCommonAttributes(const Decl *D,
llvm::GlobalValue *GV) {
setGlobalVisibility(GV, D);
@@ -387,19 +381,19 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
bool IsIncompleteFunction) {
if (!IsIncompleteFunction)
SetLLVMFunctionAttributes(FD, getTypes().getFunctionInfo(FD), F);
-
+
// Only a few attributes are set on declarations; these may later be
// overridden by a definition.
-
+
if (FD->hasAttr<DLLImportAttr>()) {
F->setLinkage(llvm::Function::DLLImportLinkage);
- } else if (FD->hasAttr<WeakAttr>() ||
+ } else if (FD->hasAttr<WeakAttr>() ||
FD->hasAttr<WeakImportAttr>()) {
// "extern_weak" is overloaded in LLVM; we probably should have
- // separate linkage types for this.
+ // separate linkage types for this.
F->setLinkage(llvm::Function::ExternalWeakLinkage);
} else {
- F->setLinkage(llvm::Function::ExternalLinkage);
+ F->setLinkage(llvm::Function::ExternalLinkage);
}
if (const SectionAttr *SA = FD->getAttr<SectionAttr>())
@@ -407,39 +401,36 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
}
void CodeGenModule::AddUsedGlobal(llvm::GlobalValue *GV) {
- assert(!GV->isDeclaration() &&
+ assert(!GV->isDeclaration() &&
"Only globals with definition can force usage.");
LLVMUsed.push_back(GV);
}
void CodeGenModule::EmitLLVMUsed() {
// Don't create llvm.used if there is no need.
- // FIXME. Runtime indicates that there might be more 'used' symbols; but not
- // necessariy. So, this test is not accurate for emptiness.
- if (LLVMUsed.empty() && !Runtime)
+ if (LLVMUsed.empty())
return;
- llvm::Type *i8PTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
-
+ const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext);
+
// Convert LLVMUsed to what ConstantArray needs.
std::vector<llvm::Constant*> UsedArray;
UsedArray.resize(LLVMUsed.size());
for (unsigned i = 0, e = LLVMUsed.size(); i != e; ++i) {
- UsedArray[i] =
- llvm::ConstantExpr::getBitCast(cast<llvm::Constant>(&*LLVMUsed[i]), i8PTy);
+ UsedArray[i] =
+ llvm::ConstantExpr::getBitCast(cast<llvm::Constant>(&*LLVMUsed[i]),
+ i8PTy);
}
-
- if (Runtime)
- Runtime->MergeMetadataGlobals(UsedArray);
+
if (UsedArray.empty())
return;
llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, UsedArray.size());
-
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(ATy, false,
+
+ llvm::GlobalVariable *GV =
+ new llvm::GlobalVariable(getModule(), ATy, false,
llvm::GlobalValue::AppendingLinkage,
llvm::ConstantArray::get(ATy, UsedArray),
- "llvm.used", &getModule());
+ "llvm.used");
GV->setSection("llvm.metadata");
}
@@ -458,59 +449,60 @@ void CodeGenModule::EmitDeferred() {
// just ignore the deferred decl.
llvm::GlobalValue *CGRef = GlobalDeclMap[getMangledName(D)];
assert(CGRef && "Deferred decl wasn't referenced?");
-
+
if (!CGRef->isDeclaration())
continue;
-
+
// Otherwise, emit the definition and move on to the next one.
EmitGlobalDefinition(D);
}
}
-/// EmitAnnotateAttr - Generate the llvm::ConstantStruct which contains the
+/// EmitAnnotateAttr - Generate the llvm::ConstantStruct which contains the
/// annotation information for a given GlobalValue. The annotation struct is
-/// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the
-/// GlobalValue being annotated. The second field is the constant string
-/// created from the AnnotateAttr's annotation. The third field is a constant
+/// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the
+/// GlobalValue being annotated. The second field is the constant string
+/// created from the AnnotateAttr's annotation. The third field is a constant
/// string containing the name of the translation unit. The fourth field is
/// the line number in the file of the annotated value declaration.
///
/// FIXME: this does not unique the annotation string constants, as llvm-gcc
/// appears to.
///
-llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV,
+llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV,
const AnnotateAttr *AA,
unsigned LineNo) {
llvm::Module *M = &getModule();
// get [N x i8] constants for the annotation string, and the filename string
// which are the 2nd and 3rd elements of the global annotation structure.
- const llvm::Type *SBP = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
- llvm::Constant *anno = llvm::ConstantArray::get(AA->getAnnotation(), true);
- llvm::Constant *unit = llvm::ConstantArray::get(M->getModuleIdentifier(),
+ const llvm::Type *SBP = llvm::Type::getInt8PtrTy(VMContext);
+ llvm::Constant *anno = llvm::ConstantArray::get(VMContext,
+ AA->getAnnotation(), true);
+ llvm::Constant *unit = llvm::ConstantArray::get(VMContext,
+ M->getModuleIdentifier(),
true);
// Get the two global values corresponding to the ConstantArrays we just
// created to hold the bytes of the strings.
- const char *StringPrefix = getContext().Target.getStringSymbolPrefix(true);
- llvm::GlobalValue *annoGV =
- new llvm::GlobalVariable(anno->getType(), false,
- llvm::GlobalValue::InternalLinkage, anno,
- GV->getName() + StringPrefix, M);
+ llvm::GlobalValue *annoGV =
+ new llvm::GlobalVariable(*M, anno->getType(), false,
+ llvm::GlobalValue::PrivateLinkage, anno,
+ GV->getName());
// translation unit name string, emitted into the llvm.metadata section.
llvm::GlobalValue *unitGV =
- new llvm::GlobalVariable(unit->getType(), false,
- llvm::GlobalValue::InternalLinkage, unit,
- StringPrefix, M);
+ new llvm::GlobalVariable(*M, unit->getType(), false,
+ llvm::GlobalValue::PrivateLinkage, unit,
+ ".str");
// Create the ConstantStruct for the global annotation.
llvm::Constant *Fields[4] = {
llvm::ConstantExpr::getBitCast(GV, SBP),
llvm::ConstantExpr::getBitCast(annoGV, SBP),
llvm::ConstantExpr::getBitCast(unitGV, SBP),
- llvm::ConstantInt::get(llvm::Type::Int32Ty, LineNo)
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), LineNo)
};
- return llvm::ConstantStruct::get(Fields, 4, false);
+ return llvm::ConstantStruct::get(VMContext, Fields, 4, false);
}
bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
@@ -521,12 +513,12 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
// Constructors and destructors should never be deferred.
- if (FD->hasAttr<ConstructorAttr>() ||
+ if (FD->hasAttr<ConstructorAttr>() ||
FD->hasAttr<DestructorAttr>())
return false;
GVALinkage Linkage = GetLinkageForFunction(getContext(), FD, Features);
-
+
// static, static inline, always_inline, and extern inline functions can
// always be deferred. Normal inline functions can be deferred in C99/C++.
if (Linkage == GVA_Internal || Linkage == GVA_C99Inline ||
@@ -534,16 +526,27 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
return true;
return false;
}
-
+
const VarDecl *VD = cast<VarDecl>(Global);
assert(VD->isFileVarDecl() && "Invalid decl");
+ // We never want to defer structs that have non-trivial constructors or
+ // destructors.
+
+ // FIXME: Handle references.
+ if (const RecordType *RT = VD->getType()->getAs<RecordType>()) {
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+ if (!RD->hasTrivialConstructor() || !RD->hasTrivialDestructor())
+ return false;
+ }
+ }
+
return VD->getStorageClass() == VarDecl::Static;
}
void CodeGenModule::EmitGlobal(GlobalDecl GD) {
- const ValueDecl *Global = GD.getDecl();
-
+ const ValueDecl *Global = cast<ValueDecl>(GD.getDecl());
+
// If this is an alias definition (which otherwise looks like a declaration)
// emit it now.
if (Global->hasAttr<AliasAttr>())
@@ -560,8 +563,8 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
// In C++, if this is marked "extern", defer code generation.
if (getLangOptions().CPlusPlus && !VD->getInit() &&
- (VD->getStorageClass() == VarDecl::Extern ||
- VD->isExternC(getContext())))
+ (VD->getStorageClass() == VarDecl::Extern ||
+ VD->isExternC()))
return;
// In C, if this isn't a definition, defer code generation.
@@ -591,8 +594,8 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
}
void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
- const ValueDecl *D = GD.getDecl();
-
+ const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
+
if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
EmitCXXConstructor(CD, GD.getCtorType());
else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D))
@@ -621,16 +624,16 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName,
if (Entry) {
if (Entry->getType()->getElementType() == Ty)
return Entry;
-
+
// Make sure the result is of the correct type.
const llvm::Type *PTy = llvm::PointerType::getUnqual(Ty);
return llvm::ConstantExpr::getBitCast(Entry, PTy);
}
-
+
// 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.
- llvm::DenseMap<const char*, GlobalDecl>::iterator DDI =
+ llvm::DenseMap<const char*, GlobalDecl>::iterator DDI =
DeferredDecls.find(MangledName);
if (DDI != DeferredDecls.end()) {
// Move the potentially referenced deferred decl to the DeferredDeclsToEmit
@@ -643,18 +646,33 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName,
// top-level declarations.
if (FD->isThisDeclarationADefinition() && MayDeferGeneration(FD))
DeferredDeclsToEmit.push_back(D);
+ // A called constructor which has no definition or declaration need be
+ // synthesized.
+ else if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
+ const CXXRecordDecl *ClassDecl =
+ cast<CXXRecordDecl>(CD->getDeclContext());
+ if (CD->isCopyConstructor(getContext()))
+ DeferredCopyConstructorToEmit(D);
+ else if (!ClassDecl->hasUserDeclaredConstructor())
+ DeferredDeclsToEmit.push_back(D);
+ }
+ else if (isa<CXXDestructorDecl>(FD))
+ DeferredDestructorToEmit(D);
+ else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
+ if (MD->isCopyAssignment())
+ DeferredCopyAssignmentToEmit(D);
}
-
+
// This function doesn't have a complete type (for example, the return
// type is an incomplete struct). Use a fake type instead, and make
// sure not to try to set attributes.
bool IsIncompleteFunction = false;
if (!isa<llvm::FunctionType>(Ty)) {
- Ty = llvm::FunctionType::get(llvm::Type::VoidTy,
+ Ty = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
std::vector<const llvm::Type*>(), false);
IsIncompleteFunction = true;
}
- llvm::Function *F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
+ llvm::Function *F = llvm::Function::Create(cast<llvm::FunctionType>(Ty),
llvm::Function::ExternalLinkage,
"", &getModule());
F->setName(MangledName);
@@ -665,6 +683,126 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName,
return F;
}
+/// Defer definition of copy constructor(s) which need be implicitly defined.
+void CodeGenModule::DeferredCopyConstructorToEmit(GlobalDecl CopyCtorDecl) {
+ const CXXConstructorDecl *CD =
+ cast<CXXConstructorDecl>(CopyCtorDecl.getDecl());
+ const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
+ if (ClassDecl->hasTrivialCopyConstructor() ||
+ ClassDecl->hasUserDeclaredCopyConstructor())
+ return;
+
+ // First make sure all direct base classes and virtual bases and non-static
+ // data mebers which need to have their copy constructors implicitly defined
+ // are defined. 12.8.p7
+ for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
+ Base != ClassDecl->bases_end(); ++Base) {
+ CXXRecordDecl *BaseClassDecl
+ = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+ if (CXXConstructorDecl *BaseCopyCtor =
+ BaseClassDecl->getCopyConstructor(Context, 0))
+ GetAddrOfCXXConstructor(BaseCopyCtor, Ctor_Complete);
+ }
+
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ FieldEnd = ClassDecl->field_end();
+ Field != FieldEnd; ++Field) {
+ QualType FieldType = Context.getCanonicalType((*Field)->getType());
+ if (const ArrayType *Array = Context.getAsArrayType(FieldType))
+ FieldType = Array->getElementType();
+ if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+ if ((*Field)->isAnonymousStructOrUnion())
+ continue;
+ CXXRecordDecl *FieldClassDecl
+ = cast<CXXRecordDecl>(FieldClassType->getDecl());
+ if (CXXConstructorDecl *FieldCopyCtor =
+ FieldClassDecl->getCopyConstructor(Context, 0))
+ GetAddrOfCXXConstructor(FieldCopyCtor, Ctor_Complete);
+ }
+ }
+ DeferredDeclsToEmit.push_back(CopyCtorDecl);
+}
+
+/// Defer definition of copy assignments which need be implicitly defined.
+void CodeGenModule::DeferredCopyAssignmentToEmit(GlobalDecl CopyAssignDecl) {
+ const CXXMethodDecl *CD = cast<CXXMethodDecl>(CopyAssignDecl.getDecl());
+ const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
+
+ if (ClassDecl->hasTrivialCopyAssignment() ||
+ ClassDecl->hasUserDeclaredCopyAssignment())
+ return;
+
+ // First make sure all direct base classes and virtual bases and non-static
+ // data mebers which need to have their copy assignments implicitly defined
+ // are defined. 12.8.p12
+ for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
+ Base != ClassDecl->bases_end(); ++Base) {
+ CXXRecordDecl *BaseClassDecl
+ = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+ const CXXMethodDecl *MD = 0;
+ if (!BaseClassDecl->hasTrivialCopyAssignment() &&
+ !BaseClassDecl->hasUserDeclaredCopyAssignment() &&
+ BaseClassDecl->hasConstCopyAssignment(getContext(), MD))
+ GetAddrOfFunction(MD, 0);
+ }
+
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ FieldEnd = ClassDecl->field_end();
+ Field != FieldEnd; ++Field) {
+ QualType FieldType = Context.getCanonicalType((*Field)->getType());
+ if (const ArrayType *Array = Context.getAsArrayType(FieldType))
+ FieldType = Array->getElementType();
+ if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+ if ((*Field)->isAnonymousStructOrUnion())
+ continue;
+ CXXRecordDecl *FieldClassDecl
+ = cast<CXXRecordDecl>(FieldClassType->getDecl());
+ const CXXMethodDecl *MD = 0;
+ if (!FieldClassDecl->hasTrivialCopyAssignment() &&
+ !FieldClassDecl->hasUserDeclaredCopyAssignment() &&
+ FieldClassDecl->hasConstCopyAssignment(getContext(), MD))
+ GetAddrOfFunction(MD, 0);
+ }
+ }
+ DeferredDeclsToEmit.push_back(CopyAssignDecl);
+}
+
+void CodeGenModule::DeferredDestructorToEmit(GlobalDecl DtorDecl) {
+ const CXXDestructorDecl *DD = cast<CXXDestructorDecl>(DtorDecl.getDecl());
+ const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext());
+ if (ClassDecl->hasTrivialDestructor() ||
+ ClassDecl->hasUserDeclaredDestructor())
+ return;
+
+ for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin();
+ Base != ClassDecl->bases_end(); ++Base) {
+ CXXRecordDecl *BaseClassDecl
+ = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+ if (const CXXDestructorDecl *BaseDtor =
+ BaseClassDecl->getDestructor(Context))
+ GetAddrOfCXXDestructor(BaseDtor, Dtor_Complete);
+ }
+
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ FieldEnd = ClassDecl->field_end();
+ Field != FieldEnd; ++Field) {
+ QualType FieldType = Context.getCanonicalType((*Field)->getType());
+ if (const ArrayType *Array = Context.getAsArrayType(FieldType))
+ FieldType = Array->getElementType();
+ if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
+ if ((*Field)->isAnonymousStructOrUnion())
+ continue;
+ CXXRecordDecl *FieldClassDecl
+ = cast<CXXRecordDecl>(FieldClassType->getDecl());
+ if (const CXXDestructorDecl *FieldDtor =
+ FieldClassDecl->getDestructor(Context))
+ GetAddrOfCXXDestructor(FieldDtor, Dtor_Complete);
+ }
+ }
+ DeferredDeclsToEmit.push_back(DtorDecl);
+}
+
+
/// GetAddrOfFunction - Return the address of the given function. If Ty is
/// non-null, then this function will use the specified type if it has to
/// create it (this occurs when we see a definition of the function).
@@ -672,8 +810,8 @@ llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD,
const llvm::Type *Ty) {
// If there was no specific requested type, just convert it now.
if (!Ty)
- Ty = getTypes().ConvertType(GD.getDecl()->getType());
- return GetOrCreateLLVMFunction(getMangledName(GD.getDecl()), Ty, GD);
+ Ty = getTypes().ConvertType(cast<ValueDecl>(GD.getDecl())->getType());
+ return GetOrCreateLLVMFunction(getMangledName(GD), Ty, GD);
}
/// CreateRuntimeFunction - Create a new runtime function with the specified
@@ -701,15 +839,15 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName,
if (Entry) {
if (Entry->getType() == Ty)
return Entry;
-
+
// Make sure the result is of the correct type.
return llvm::ConstantExpr::getBitCast(Entry, Ty);
}
-
+
// 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.
- llvm::DenseMap<const char*, GlobalDecl>::iterator DDI =
+ llvm::DenseMap<const char*, GlobalDecl>::iterator DDI =
DeferredDecls.find(MangledName);
if (DDI != DeferredDecls.end()) {
// Move the potentially referenced deferred decl to the DeferredDeclsToEmit
@@ -717,11 +855,11 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName,
DeferredDeclsToEmit.push_back(DDI->second);
DeferredDecls.erase(DDI);
}
-
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(Ty->getElementType(), false,
+
+ llvm::GlobalVariable *GV =
+ new llvm::GlobalVariable(getModule(), Ty->getElementType(), false,
llvm::GlobalValue::ExternalLinkage,
- 0, "", &getModule(),
+ 0, "", 0,
false, Ty->getAddressSpace());
GV->setName(MangledName);
@@ -735,13 +873,13 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName,
if (D->getStorageClass() == VarDecl::PrivateExtern)
GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
- if (D->hasAttr<WeakAttr>() ||
+ if (D->hasAttr<WeakAttr>() ||
D->hasAttr<WeakImportAttr>())
GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
GV->setThreadLocal(D->isThreadSpecified());
}
-
+
return Entry = GV;
}
@@ -756,8 +894,8 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
QualType ASTTy = D->getType();
if (Ty == 0)
Ty = getTypes().ConvertTypeForMem(ASTTy);
-
- const llvm::PointerType *PTy =
+
+ const llvm::PointerType *PTy =
llvm::PointerType::get(Ty, ASTTy.getAddressSpace());
return GetOrCreateLLVMGlobal(getMangledName(D), PTy, D);
}
@@ -781,7 +919,7 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) {
// later.
const char *MangledName = getMangledName(D);
if (GlobalDeclMap.count(MangledName) == 0) {
- DeferredDecls[MangledName] = GlobalDecl(D);
+ DeferredDecls[MangledName] = D;
return;
}
}
@@ -793,7 +931,7 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) {
void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
llvm::Constant *Init = 0;
QualType ASTTy = D->getType();
-
+
if (D->getInit() == 0) {
// This is a tentative definition; tentative definitions are
// implicitly initialized with { 0 }.
@@ -805,28 +943,36 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
// exists. A use may still exists, however, so we still may need
// to do a RAUW.
assert(!ASTTy->isIncompleteType() && "Unexpected incomplete type");
- Init = llvm::Constant::getNullValue(getTypes().ConvertTypeForMem(ASTTy));
+ Init = EmitNullConstant(D->getType());
} else {
Init = EmitConstantExpr(D->getInit(), D->getType());
+
if (!Init) {
- ErrorUnsupported(D, "static initializer");
QualType T = D->getInit()->getType();
- Init = llvm::UndefValue::get(getTypes().ConvertType(T));
+ if (getLangOptions().CPlusPlus) {
+ CXXGlobalInits.push_back(D);
+ Init = EmitNullConstant(T);
+ } else {
+ ErrorUnsupported(D, "static initializer");
+ Init = llvm::UndefValue::get(getTypes().ConvertType(T));
+ }
}
}
const llvm::Type* InitType = Init->getType();
llvm::Constant *Entry = GetAddrOfGlobalVar(D, InitType);
-
+
// Strip off a bitcast if we got one back.
if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
- assert(CE->getOpcode() == llvm::Instruction::BitCast);
+ assert(CE->getOpcode() == llvm::Instruction::BitCast ||
+ // all zero index gep.
+ CE->getOpcode() == llvm::Instruction::GetElementPtr);
Entry = CE->getOperand(0);
}
-
+
// Entry is now either a Function or GlobalVariable.
llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Entry);
-
+
// We have a definition after a declaration with the wrong type.
// We must make a new GlobalVariable* and update everything that used OldGV
// (a declaration or tentative definition) with the new GlobalVariable*
@@ -839,7 +985,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
if (GV == 0 ||
GV->getType()->getElementType() != InitType ||
GV->getType()->getAddressSpace() != ASTTy.getAddressSpace()) {
-
+
// Remove the old entry from GlobalDeclMap so that we'll create a new one.
GlobalDeclMap.erase(getMangledName(D));
@@ -848,7 +994,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
GV->takeName(cast<llvm::GlobalValue>(Entry));
// Replace all uses of the old global with the new global
- llvm::Constant *NewPtrForOldDecl =
+ llvm::Constant *NewPtrForOldDecl =
llvm::ConstantExpr::getBitCast(GV, Entry->getType());
Entry->replaceAllUsesWith(NewPtrForOldDecl);
@@ -863,22 +1009,38 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
}
GV->setInitializer(Init);
- GV->setConstant(D->getType().isConstant(Context));
+
+ // If it is safe to mark the global 'constant', do so now.
+ GV->setConstant(false);
+ if (D->getType().isConstant(Context)) {
+ // FIXME: In C++, if the variable has a non-trivial ctor/dtor or any mutable
+ // members, it cannot be declared "LLVM const".
+ GV->setConstant(true);
+ }
+
GV->setAlignment(getContext().getDeclAlignInBytes(D));
// Set the llvm linkage type as appropriate.
- if (D->getStorageClass() == VarDecl::Static)
+ if (D->isInAnonymousNamespace())
+ GV->setLinkage(llvm::Function::InternalLinkage);
+ else if (D->getStorageClass() == VarDecl::Static)
GV->setLinkage(llvm::Function::InternalLinkage);
else if (D->hasAttr<DLLImportAttr>())
GV->setLinkage(llvm::Function::DLLImportLinkage);
else if (D->hasAttr<DLLExportAttr>())
GV->setLinkage(llvm::Function::DLLExportLinkage);
- else if (D->hasAttr<WeakAttr>())
- GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage);
- else if (!CompileOpts.NoCommon &&
- (!D->hasExternalStorage() && !D->getInit()))
+ else if (D->hasAttr<WeakAttr>()) {
+ if (GV->isConstant())
+ GV->setLinkage(llvm::GlobalVariable::WeakODRLinkage);
+ else
+ GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage);
+ } else if (!CompileOpts.NoCommon &&
+ !D->hasExternalStorage() && !D->getInit() &&
+ !D->getAttr<SectionAttr>()) {
GV->setLinkage(llvm::GlobalVariable::CommonLinkage);
- else
+ // common vars aren't constant even if declared const.
+ GV->setConstant(false);
+ } else
GV->setLinkage(llvm::GlobalVariable::ExternalLinkage);
SetCommonAttributes(D, GV);
@@ -904,7 +1066,7 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old,
// If we're redefining a global as a function, don't transform it.
llvm::Function *OldFn = dyn_cast<llvm::Function>(Old);
if (OldFn == 0) return;
-
+
const llvm::Type *NewRetTy = NewFn->getReturnType();
llvm::SmallVector<llvm::Value*, 4> ArgList;
@@ -914,7 +1076,7 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old,
unsigned OpNo = UI.getOperandNo();
llvm::CallInst *CI = dyn_cast<llvm::CallInst>(*UI++);
if (!CI || OpNo != 0) continue;
-
+
// If the return types don't match exactly, and if the call isn't dead, then
// we can't transform this call.
if (CI->getType() != NewRetTy && !CI->use_empty())
@@ -935,21 +1097,26 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old,
}
if (DontTransform)
continue;
-
+
// Okay, we can transform this. Create the new call instruction and copy
// over the required information.
ArgList.append(CI->op_begin()+1, CI->op_begin()+1+ArgNo);
llvm::CallInst *NewCall = llvm::CallInst::Create(NewFn, ArgList.begin(),
ArgList.end(), "", CI);
ArgList.clear();
- if (NewCall->getType() != llvm::Type::VoidTy)
+ if (!NewCall->getType()->isVoidTy())
NewCall->takeName(CI);
- NewCall->setCallingConv(CI->getCallingConv());
NewCall->setAttributes(CI->getAttributes());
+ NewCall->setCallingConv(CI->getCallingConv());
// Finally, remove the old call, replacing any uses with the new one.
if (!CI->use_empty())
CI->replaceAllUsesWith(NewCall);
+
+ // Copy any custom metadata attached with CI.
+ llvm::MetadataContext &TheMetadata = CI->getContext().getMetadata();
+ TheMetadata.copyMD(CI, NewCall);
+
CI->eraseFromParent();
}
}
@@ -958,21 +1125,21 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old,
void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
const llvm::FunctionType *Ty;
const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl());
-
+
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
- bool isVariadic = D->getType()->getAsFunctionProtoType()->isVariadic();
-
+ bool isVariadic = D->getType()->getAs<FunctionProtoType>()->isVariadic();
+
Ty = getTypes().GetFunctionType(getTypes().getFunctionInfo(MD), isVariadic);
} else {
Ty = cast<llvm::FunctionType>(getTypes().ConvertType(D->getType()));
-
+
// As a special case, make sure that definitions of K&R function
// "type foo()" aren't declared as varargs (which forces the backend
// to do unnecessary work).
if (D->getType()->isFunctionNoProtoType()) {
assert(Ty->isVarArg() && "Didn't lower type as expected");
- // Due to stret, the lowered function could have arguments.
- // Just create the same type as was lowered by ConvertType
+ // Due to stret, the lowered function could have arguments.
+ // Just create the same type as was lowered by ConvertType
// but strip off the varargs bit.
std::vector<const llvm::Type*> Args(Ty->param_begin(), Ty->param_end());
Ty = llvm::FunctionType::get(Ty->getReturnType(), Args, false);
@@ -981,17 +1148,17 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
// Get or create the prototype for the function.
llvm::Constant *Entry = GetAddrOfFunction(GD, Ty);
-
+
// Strip off a bitcast if we got one back.
if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
assert(CE->getOpcode() == llvm::Instruction::BitCast);
Entry = CE->getOperand(0);
}
-
-
+
+
if (cast<llvm::GlobalValue>(Entry)->getType()->getElementType() != Ty) {
llvm::GlobalValue *OldFn = cast<llvm::GlobalValue>(Entry);
-
+
// If the types mismatch then we have to rewrite the definition.
assert(OldFn->isDeclaration() &&
"Shouldn't replace non-declaration");
@@ -1007,7 +1174,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
GlobalDeclMap.erase(getMangledName(D));
llvm::Function *NewFn = cast<llvm::Function>(GetAddrOfFunction(GD, Ty));
NewFn->takeName(OldFn);
-
+
// If this is an implementation of a function without a prototype, try to
// replace any existing uses of the function (which may be calls) with uses
// of the new function
@@ -1015,27 +1182,27 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
ReplaceUsesOfNonProtoTypeWithRealFunction(OldFn, NewFn);
OldFn->removeDeadConstantUsers();
}
-
+
// Replace uses of F with the Function we will endow with a body.
if (!Entry->use_empty()) {
- llvm::Constant *NewPtrForOldDecl =
+ llvm::Constant *NewPtrForOldDecl =
llvm::ConstantExpr::getBitCast(NewFn, Entry->getType());
Entry->replaceAllUsesWith(NewPtrForOldDecl);
}
-
+
// Ok, delete the old function now, which is dead.
OldFn->eraseFromParent();
-
+
Entry = NewFn;
}
-
+
llvm::Function *Fn = cast<llvm::Function>(Entry);
CodeGenFunction(*this).GenerateCode(D, Fn);
SetFunctionDefinitionAttributes(D, Fn);
SetLLVMFunctionAttributesForDefinition(D, Fn);
-
+
if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>())
AddGlobalCtor(Fn, CA->getPriority());
if (const DestructorAttr *DA = D->getAttr<DestructorAttr>())
@@ -1047,7 +1214,7 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {
assert(AA && "Not an alias?");
const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
-
+
// Unique the name through the identifier table.
const char *AliaseeName = AA->getAliasee().c_str();
AliaseeName = getContext().Idents.get(AliaseeName).getName();
@@ -1062,22 +1229,22 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {
llvm::PointerType::getUnqual(DeclTy), 0);
// Create the new alias itself, but don't set a name yet.
- llvm::GlobalValue *GA =
+ llvm::GlobalValue *GA =
new llvm::GlobalAlias(Aliasee->getType(),
llvm::Function::ExternalLinkage,
"", Aliasee, &getModule());
-
+
// See if there is already something with the alias' name in the module.
const char *MangledName = getMangledName(D);
llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName];
-
+
if (Entry && !Entry->isDeclaration()) {
// If there is a definition in the module, then it wins over the alias.
// This is dubious, but allow it to be safe. Just ignore the alias.
GA->eraseFromParent();
return;
}
-
+
if (Entry) {
// If there is a declaration in the module, then we had an extern followed
// by the alias, as in:
@@ -1086,12 +1253,12 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {
// int test6() __attribute__((alias("test7")));
//
// Remove it and replace uses of it with the alias.
-
+
Entry->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GA,
Entry->getType()));
Entry->eraseFromParent();
}
-
+
// Now we know that there is no conflict, set the name.
Entry = GA;
GA->setName(MangledName);
@@ -1107,7 +1274,7 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {
} else {
GA->setLinkage(llvm::Function::DLLExportLinkage);
}
- } else if (D->hasAttr<WeakAttr>() ||
+ } else if (D->hasAttr<WeakAttr>() ||
D->hasAttr<WeakImportAttr>()) {
GA->setLinkage(llvm::Function::WeakAnyLinkage);
}
@@ -1117,28 +1284,28 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {
/// getBuiltinLibFunction - Given a builtin id for a function like
/// "__builtin_fabsf", return a Function* for "fabsf".
-llvm::Value *CodeGenModule::getBuiltinLibFunction(unsigned BuiltinID) {
+llvm::Value *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
+ unsigned BuiltinID) {
assert((Context.BuiltinInfo.isLibFunction(BuiltinID) ||
- Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) &&
+ Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) &&
"isn't a lib fn");
-
+
// Get the name, skip over the __builtin_ prefix (if necessary).
const char *Name = Context.BuiltinInfo.GetName(BuiltinID);
if (Context.BuiltinInfo.isLibFunction(BuiltinID))
Name += 10;
-
+
// Get the type for the builtin.
ASTContext::GetBuiltinTypeError Error;
QualType Type = Context.GetBuiltinType(BuiltinID, Error);
assert(Error == ASTContext::GE_None && "Can't get builtin type");
- const llvm::FunctionType *Ty =
+ const llvm::FunctionType *Ty =
cast<llvm::FunctionType>(getTypes().ConvertType(Type));
// Unique the name through the identifier table.
Name = getContext().Idents.get(Name).getName();
- // FIXME: param attributes for sext/zext etc.
- return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl());
+ return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl(FD));
}
llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys,
@@ -1149,186 +1316,167 @@ llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys,
llvm::Function *CodeGenModule::getMemCpyFn() {
if (MemCpyFn) return MemCpyFn;
- const llvm::Type *IntPtr = TheTargetData.getIntPtrType();
+ const llvm::Type *IntPtr = TheTargetData.getIntPtrType(VMContext);
return MemCpyFn = getIntrinsic(llvm::Intrinsic::memcpy, &IntPtr, 1);
}
llvm::Function *CodeGenModule::getMemMoveFn() {
if (MemMoveFn) return MemMoveFn;
- const llvm::Type *IntPtr = TheTargetData.getIntPtrType();
+ const llvm::Type *IntPtr = TheTargetData.getIntPtrType(VMContext);
return MemMoveFn = getIntrinsic(llvm::Intrinsic::memmove, &IntPtr, 1);
}
llvm::Function *CodeGenModule::getMemSetFn() {
if (MemSetFn) return MemSetFn;
- const llvm::Type *IntPtr = TheTargetData.getIntPtrType();
+ const llvm::Type *IntPtr = TheTargetData.getIntPtrType(VMContext);
return MemSetFn = getIntrinsic(llvm::Intrinsic::memset, &IntPtr, 1);
}
-static void appendFieldAndPadding(CodeGenModule &CGM,
- std::vector<llvm::Constant*>& Fields,
- FieldDecl *FieldD, FieldDecl *NextFieldD,
- llvm::Constant* Field,
- RecordDecl* RD, const llvm::StructType *STy) {
- // Append the field.
- Fields.push_back(Field);
-
- int StructFieldNo = CGM.getTypes().getLLVMFieldNo(FieldD);
-
- int NextStructFieldNo;
- if (!NextFieldD) {
- NextStructFieldNo = STy->getNumElements();
- } else {
- NextStructFieldNo = CGM.getTypes().getLLVMFieldNo(NextFieldD);
+static llvm::StringMapEntry<llvm::Constant*> &
+GetConstantCFStringEntry(llvm::StringMap<llvm::Constant*> &Map,
+ const StringLiteral *Literal,
+ bool TargetIsLSB,
+ bool &IsUTF16,
+ unsigned &StringLength) {
+ unsigned NumBytes = Literal->getByteLength();
+
+ // Check for simple case.
+ if (!Literal->containsNonAsciiOrNull()) {
+ StringLength = NumBytes;
+ return Map.GetOrCreateValue(llvm::StringRef(Literal->getStrData(),
+ StringLength));
}
-
- // Append padding
- for (int i = StructFieldNo + 1; i < NextStructFieldNo; i++) {
- llvm::Constant *C =
- llvm::Constant::getNullValue(STy->getElementType(StructFieldNo + 1));
-
- Fields.push_back(C);
+
+ // Otherwise, convert the UTF8 literals into a byte string.
+ llvm::SmallVector<UTF16, 128> ToBuf(NumBytes);
+ const UTF8 *FromPtr = (UTF8 *)Literal->getStrData();
+ UTF16 *ToPtr = &ToBuf[0];
+
+ ConversionResult Result = ConvertUTF8toUTF16(&FromPtr, FromPtr + NumBytes,
+ &ToPtr, ToPtr + NumBytes,
+ strictConversion);
+
+ // Check for conversion failure.
+ if (Result != conversionOK) {
+ // FIXME: Have Sema::CheckObjCString() validate the UTF-8 string and remove
+ // this duplicate code.
+ assert(Result == sourceIllegal && "UTF-8 to UTF-16 conversion failed");
+ StringLength = NumBytes;
+ return Map.GetOrCreateValue(llvm::StringRef(Literal->getStrData(),
+ StringLength));
}
+
+ // ConvertUTF8toUTF16 returns the length in ToPtr.
+ StringLength = ToPtr - &ToBuf[0];
+
+ // Render the UTF-16 string into a byte array and convert to the target byte
+ // order.
+ //
+ // FIXME: This isn't something we should need to do here.
+ llvm::SmallString<128> AsBytes;
+ AsBytes.reserve(StringLength * 2);
+ for (unsigned i = 0; i != StringLength; ++i) {
+ unsigned short Val = ToBuf[i];
+ if (TargetIsLSB) {
+ AsBytes.push_back(Val & 0xFF);
+ AsBytes.push_back(Val >> 8);
+ } else {
+ AsBytes.push_back(Val >> 8);
+ AsBytes.push_back(Val & 0xFF);
+ }
+ }
+ // Append one extra null character, the second is automatically added by our
+ // caller.
+ AsBytes.push_back(0);
+
+ IsUTF16 = true;
+ return Map.GetOrCreateValue(llvm::StringRef(AsBytes.data(), AsBytes.size()));
}
-llvm::Constant *CodeGenModule::
-GetAddrOfConstantCFString(const StringLiteral *Literal) {
- std::string str;
+llvm::Constant *
+CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) {
unsigned StringLength = 0;
-
bool isUTF16 = false;
- if (Literal->containsNonAsciiOrNull()) {
- // Convert from UTF-8 to UTF-16.
- llvm::SmallVector<UTF16, 128> ToBuf(Literal->getByteLength());
- const UTF8 *FromPtr = (UTF8 *)Literal->getStrData();
- UTF16 *ToPtr = &ToBuf[0];
-
- ConversionResult Result;
- Result = ConvertUTF8toUTF16(&FromPtr, FromPtr+Literal->getByteLength(),
- &ToPtr, ToPtr+Literal->getByteLength(),
- strictConversion);
- if (Result == conversionOK) {
- // FIXME: Storing UTF-16 in a C string is a hack to test Unicode strings
- // without doing more surgery to this routine. Since we aren't explicitly
- // checking for endianness here, it's also a bug (when generating code for
- // a target that doesn't match the host endianness). Modeling this as an
- // i16 array is likely the cleanest solution.
- StringLength = ToPtr-&ToBuf[0];
- str.assign((char *)&ToBuf[0], StringLength*2);// Twice as many UTF8 chars.
- isUTF16 = true;
- } else if (Result == sourceIllegal) {
- // FIXME: Have Sema::CheckObjCString() validate the UTF-8 string.
- str.assign(Literal->getStrData(), Literal->getByteLength());
- StringLength = str.length();
- } else
- assert(Result == conversionOK && "UTF-8 to UTF-16 conversion failed");
-
- } else {
- str.assign(Literal->getStrData(), Literal->getByteLength());
- StringLength = str.length();
- }
- llvm::StringMapEntry<llvm::Constant *> &Entry =
- CFConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
-
+ llvm::StringMapEntry<llvm::Constant*> &Entry =
+ GetConstantCFStringEntry(CFConstantStringMap, Literal,
+ getTargetData().isLittleEndian(),
+ isUTF16, StringLength);
+
if (llvm::Constant *C = Entry.getValue())
return C;
-
- llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
+
+ llvm::Constant *Zero =
+ llvm::Constant::getNullValue(llvm::Type::getInt32Ty(VMContext));
llvm::Constant *Zeros[] = { Zero, Zero };
-
+
+ // If we don't already have it, get __CFConstantStringClassReference.
if (!CFConstantStringClassRef) {
const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
Ty = llvm::ArrayType::get(Ty, 0);
-
- // FIXME: This is fairly broken if __CFConstantStringClassReference is
- // already defined, in that it will get renamed and the user will most
- // likely see an opaque error message. This is a general issue with relying
- // on particular names.
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(Ty, false,
- llvm::GlobalVariable::ExternalLinkage, 0,
- "__CFConstantStringClassReference",
- &getModule());
-
+ llvm::Constant *GV = CreateRuntimeVariable(Ty,
+ "__CFConstantStringClassReference");
// Decay array -> ptr
CFConstantStringClassRef =
llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2);
}
-
+
QualType CFTy = getContext().getCFConstantStringType();
- RecordDecl *CFRD = CFTy->getAsRecordType()->getDecl();
- const llvm::StructType *STy =
+ const llvm::StructType *STy =
cast<llvm::StructType>(getTypes().ConvertType(CFTy));
- std::vector<llvm::Constant*> Fields;
- RecordDecl::field_iterator Field = CFRD->field_begin();
+ std::vector<llvm::Constant*> Fields(4);
// Class pointer.
- FieldDecl *CurField = *Field++;
- FieldDecl *NextField = *Field++;
- appendFieldAndPadding(*this, Fields, CurField, NextField,
- CFConstantStringClassRef, CFRD, STy);
-
+ Fields[0] = CFConstantStringClassRef;
+
// Flags.
- CurField = NextField;
- NextField = *Field++;
const llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy);
- appendFieldAndPadding(*this, Fields, CurField, NextField,
- isUTF16 ? llvm::ConstantInt::get(Ty, 0x07d0)
- : llvm::ConstantInt::get(Ty, 0x07C8),
- CFRD, STy);
-
+ Fields[1] = isUTF16 ? llvm::ConstantInt::get(Ty, 0x07d0) :
+ llvm::ConstantInt::get(Ty, 0x07C8);
+
// String pointer.
- CurField = NextField;
- NextField = *Field++;
- llvm::Constant *C = llvm::ConstantArray::get(str);
+ llvm::Constant *C = llvm::ConstantArray::get(VMContext, Entry.getKey().str());
- const char *Sect, *Prefix;
+ const char *Sect = 0;
+ llvm::GlobalValue::LinkageTypes Linkage;
bool isConstant;
if (isUTF16) {
- Prefix = getContext().Target.getUnicodeStringSymbolPrefix();
Sect = getContext().Target.getUnicodeStringSection();
- // FIXME: Why does GCC not set constant here?
- isConstant = false;
- } else {
- Prefix = getContext().Target.getStringSymbolPrefix(true);
- Sect = getContext().Target.getCFStringDataSection();
- // FIXME: -fwritable-strings should probably affect this, but we
- // are following gcc here.
+ // FIXME: why do utf strings get "_" labels instead of "L" labels?
+ Linkage = llvm::GlobalValue::InternalLinkage;
+ // Note: -fwritable-strings doesn't make unicode CFStrings writable, but
+ // does make plain ascii ones writable.
isConstant = true;
+ } else {
+ Linkage = llvm::GlobalValue::PrivateLinkage;
+ isConstant = !Features.WritableStrings;
}
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(C->getType(), isConstant,
- llvm::GlobalValue::InternalLinkage,
- C, Prefix, &getModule());
+
+ llvm::GlobalVariable *GV =
+ new llvm::GlobalVariable(getModule(), C->getType(), isConstant, Linkage, C,
+ ".str");
if (Sect)
GV->setSection(Sect);
if (isUTF16) {
unsigned Align = getContext().getTypeAlign(getContext().ShortTy)/8;
- GV->setAlignment(Align);
+ GV->setAlignment(Align);
}
- appendFieldAndPadding(*this, Fields, CurField, NextField,
- llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2),
- CFRD, STy);
-
+ Fields[2] = llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2);
+
// String length.
- CurField = NextField;
- NextField = 0;
Ty = getTypes().ConvertType(getContext().LongTy);
- appendFieldAndPadding(*this, Fields, CurField, NextField,
- llvm::ConstantInt::get(Ty, StringLength), CFRD, STy);
-
+ Fields[3] = llvm::ConstantInt::get(Ty, StringLength);
+
// The struct.
C = llvm::ConstantStruct::get(STy, Fields);
- GV = new llvm::GlobalVariable(C->getType(), true,
- llvm::GlobalVariable::InternalLinkage, C,
- getContext().Target.getCFStringSymbolPrefix(),
- &getModule());
+ GV = new llvm::GlobalVariable(getModule(), C->getType(), true,
+ llvm::GlobalVariable::PrivateLinkage, C,
+ "_unnamed_cfstring_");
if (const char *Sect = getContext().Target.getCFStringSection())
GV->setSection(Sect);
Entry.setValue(GV);
-
+
return GV;
}
@@ -1341,16 +1489,16 @@ std::string CodeGenModule::GetStringForStringLiteral(const StringLiteral *E) {
const ConstantArrayType *CAT =
getContext().getAsConstantArrayType(E->getType());
assert(CAT && "String isn't pointer or array!");
-
+
// Resize the string to the right size.
std::string Str(StrData, StrData+Len);
uint64_t RealLen = CAT->getSize().getZExtValue();
-
+
if (E->isWide())
RealLen *= getContext().Target.getWCharWidth()/8;
-
+
Str.resize(RealLen, '\0');
-
+
return Str;
}
@@ -1374,17 +1522,18 @@ CodeGenModule::GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *E) {
/// GenerateWritableString -- Creates storage for a string literal.
-static llvm::Constant *GenerateStringLiteral(const std::string &str,
+static llvm::Constant *GenerateStringLiteral(const std::string &str,
bool constant,
CodeGenModule &CGM,
const char *GlobalName) {
// Create Constant for this string literal. Don't add a '\0'.
- llvm::Constant *C = llvm::ConstantArray::get(str, false);
-
+ llvm::Constant *C =
+ llvm::ConstantArray::get(CGM.getLLVMContext(), str, false);
+
// Create a global variable for this string
- return new llvm::GlobalVariable(C->getType(), constant,
- llvm::GlobalValue::InternalLinkage,
- C, GlobalName, &CGM.getModule());
+ return new llvm::GlobalVariable(CGM.getModule(), C->getType(), constant,
+ llvm::GlobalValue::PrivateLinkage,
+ C, GlobalName);
}
/// GetAddrOfConstantString - Returns a pointer to a character array
@@ -1401,14 +1550,14 @@ llvm::Constant *CodeGenModule::GetAddrOfConstantString(const std::string &str,
// Get the default prefix if a name wasn't specified.
if (!GlobalName)
- GlobalName = getContext().Target.getStringSymbolPrefix(IsConstant);
+ GlobalName = ".str";
// Don't share any string literals if strings aren't constant.
if (!IsConstant)
return GenerateStringLiteral(str, false, *this, GlobalName);
-
- llvm::StringMapEntry<llvm::Constant *> &Entry =
- ConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
+
+ llvm::StringMapEntry<llvm::Constant *> &Entry =
+ ConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
if (Entry.getValue())
return Entry.getValue();
@@ -1429,12 +1578,12 @@ llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &str,
/// EmitObjCPropertyImplementations - Emit information for synthesized
/// properties for an implementation.
-void CodeGenModule::EmitObjCPropertyImplementations(const
+void CodeGenModule::EmitObjCPropertyImplementations(const
ObjCImplementationDecl *D) {
- for (ObjCImplementationDecl::propimpl_iterator
+ for (ObjCImplementationDecl::propimpl_iterator
i = D->propimpl_begin(), e = D->propimpl_end(); i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
-
+
// Dynamic is just for type-checking.
if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
ObjCPropertyDecl *PD = PID->getPropertyDecl();
@@ -1464,7 +1613,8 @@ void CodeGenModule::EmitNamespace(const NamespaceDecl *ND) {
// EmitLinkageSpec - Emit all declarations in a linkage spec.
void CodeGenModule::EmitLinkageSpec(const LinkageSpecDecl *LSD) {
- if (LSD->getLanguage() != LinkageSpecDecl::lang_c) {
+ if (LSD->getLanguage() != LinkageSpecDecl::lang_c &&
+ LSD->getLanguage() != LinkageSpecDecl::lang_cxx) {
ErrorUnsupported(LSD, "linkage spec");
return;
}
@@ -1485,18 +1635,20 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
// Ignore dependent declarations.
if (D->getDeclContext() && D->getDeclContext()->isDependentContext())
return;
-
+
switch (D->getKind()) {
+ case Decl::CXXConversion:
case Decl::CXXMethod:
case Decl::Function:
// Skip function templates
if (cast<FunctionDecl>(D)->getDescribedFunctionTemplate())
return;
+
+ EmitGlobal(cast<FunctionDecl>(D));
+ break;
- // Fall through
-
case Decl::Var:
- EmitGlobal(GlobalDecl(cast<ValueDecl>(D)));
+ EmitGlobal(cast<VarDecl>(D));
break;
// C++ Decls
@@ -1505,8 +1657,10 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
break;
// No code generation needed.
case Decl::Using:
+ case Decl::UsingDirective:
case Decl::ClassTemplate:
case Decl::FunctionTemplate:
+ case Decl::NamespaceAlias:
break;
case Decl::CXXConstructor:
EmitCXXConstructors(cast<CXXConstructorDecl>(D));
@@ -1520,7 +1674,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
break;
// Objective-C Decls
-
+
// Forward declarations, no (immediate) code generation.
case Decl::ObjCClass:
case Decl::ObjCForwardProtocol:
@@ -1543,7 +1697,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
EmitObjCPropertyImplementations(OMD);
Runtime->GenerateClass(OMD);
break;
- }
+ }
case Decl::ObjCMethod: {
ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(D);
// If this is not a prototype, emit the body.
@@ -1551,7 +1705,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
CodeGenFunction(*this).GenerateObjCMethod(OMD);
break;
}
- case Decl::ObjCCompatibleAlias:
+ case Decl::ObjCCompatibleAlias:
// compatibility-alias is a directive and has no code gen.
break;
@@ -1563,7 +1717,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
FileScopeAsmDecl *AD = cast<FileScopeAsmDecl>(D);
std::string AsmString(AD->getAsmString()->getStrData(),
AD->getAsmString()->getByteLength());
-
+
const std::string &S = getModule().getModuleInlineAsm();
if (S.empty())
getModule().setModuleInlineAsm(AsmString);
@@ -1571,8 +1725,8 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
getModule().setModuleInlineAsm(S + '\n' + AsmString);
break;
}
-
- default:
+
+ default:
// Make sure we handled everything we should, every other kind is a
// non-top-level decl. FIXME: Would be nice to have an isTopLevelDeclKind
// function. Need to recode Decl::Kind to do that easily.