diff options
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 149 |
1 files changed, 86 insertions, 63 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index cf504a7c2a0c..5a552c490ac6 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -20,6 +20,7 @@ #include "TargetInfo.h" #include "clang/CodeGen/CodeGenOptions.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/RecordLayout.h" @@ -131,6 +132,10 @@ CodeGenModule::getDeclVisibilityMode(const Decl *D) const { } } + // This decl should have the same visibility as its parent. + if (const DeclContext *DC = D->getDeclContext()) + return getDeclVisibilityMode(cast<Decl>(DC)); + return getLangOptions().getVisibilityMode(); } @@ -254,34 +259,40 @@ void CodeGenModule::EmitAnnotations() { static CodeGenModule::GVALinkage 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; + CodeGenModule::GVALinkage External = CodeGenModule::GVA_StrongExternal; - // "static" functions get internal linkage. - if (FD->getStorageClass() == FunctionDecl::Static && !isa<CXXMethodDecl>(FD)) - return CodeGenModule::GVA_Internal; + Linkage L = FD->getLinkage(); + if (L == ExternalLinkage && Context.getLangOptions().CPlusPlus && + FD->getType()->getLinkage() == UniqueExternalLinkage) + L = UniqueExternalLinkage; - // 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) { - TemplateSpecializationKind TSK = FD->getTemplateSpecializationKind(); + switch (L) { + case NoLinkage: + case InternalLinkage: + case UniqueExternalLinkage: + return CodeGenModule::GVA_Internal; - if (TSK == TSK_ExplicitInstantiationDefinition) { - // If a function has been explicitly instantiated, then it should - // always have strong external linkage. + case ExternalLinkage: + switch (FD->getTemplateSpecializationKind()) { + case TSK_Undeclared: + case TSK_ExplicitSpecialization: + External = CodeGenModule::GVA_StrongExternal; + break; + + case TSK_ExplicitInstantiationDefinition: + // FIXME: explicit instantiation definitions should use weak linkage return CodeGenModule::GVA_StrongExternal; - } - - if (TSK == TSK_ImplicitInstantiation) + + case TSK_ExplicitInstantiationDeclaration: + case TSK_ImplicitInstantiation: External = CodeGenModule::GVA_TemplateInstantiation; + break; + } } if (!FD->isInlined()) return External; - + if (!Features.CPlusPlus || FD->hasAttr<GNUInlineAttr>()) { // GNU or C99 inline semantics. Determine whether this symbol should be // externally visible. @@ -402,11 +413,13 @@ void CodeGenModule::SetInternalFunctionAttributes(const Decl *D, SetCommonAttributes(D, F); } -void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD, +void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, bool IsIncompleteFunction) { + const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); + if (!IsIncompleteFunction) - SetLLVMFunctionAttributes(FD, getTypes().getFunctionInfo(FD), F); + SetLLVMFunctionAttributes(FD, getTypes().getFunctionInfo(GD), F); // Only a few attributes are set on declarations; these may later be // overridden by a definition. @@ -580,14 +593,24 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { // Static data may be deferred, but out-of-line static data members // cannot be. - if (VD->isInAnonymousNamespace()) - return true; - if (VD->getLinkage() == VarDecl::InternalLinkage) { + Linkage L = VD->getLinkage(); + if (L == ExternalLinkage && getContext().getLangOptions().CPlusPlus && + VD->getType()->getLinkage() == UniqueExternalLinkage) + L = UniqueExternalLinkage; + + switch (L) { + case NoLinkage: + case InternalLinkage: + case UniqueExternalLinkage: // Initializer has side effects? if (VD->getInit() && VD->getInit()->HasSideEffects(Context)) return false; return !(VD->isStaticDataMember() && VD->isOutOfLine()); + + case ExternalLinkage: + break; } + return false; } @@ -608,20 +631,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { const VarDecl *VD = cast<VarDecl>(Global); assert(VD->isFileVarDecl() && "Cannot emit local var decl as global."); - if (getLangOptions().CPlusPlus && !VD->getInit()) { - // In C++, if this is marked "extern", defer code generation. - if (VD->getStorageClass() == VarDecl::Extern || VD->isExternC()) - return; - - // If this is a declaration of an explicit specialization of a static - // data member in a class template, don't emit it. - if (VD->isStaticDataMember() && - VD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) - return; - } - - // In C, if this isn't a definition, defer code generation. - if (!getLangOptions().CPlusPlus && !VD->getInit()) + if (VD->isThisDeclarationADefinition() != VarDecl::Definition) return; } @@ -715,8 +725,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName, "", &getModule()); F->setName(MangledName); if (D.getDecl()) - SetFunctionAttributes(cast<FunctionDecl>(D.getDecl()), F, - IsIncompleteFunction); + SetFunctionAttributes(D, F, IsIncompleteFunction); Entry = F; // This is the first use or definition of a mangled name. If there is a @@ -774,7 +783,7 @@ CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy, } static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D) { - if (!D->getType().isConstant(Context)) + if (!D->getType().isConstant(Context) && !D->getType()->isReferenceType()) return false; if (Context.getLangOptions().CPlusPlus && Context.getBaseElementType(D->getType())->getAs<RecordType>()) { @@ -941,16 +950,30 @@ CodeGenModule::getVtableLinkage(const CXXRecordDecl *RD) { static CodeGenModule::GVALinkage GetLinkageForVariable(ASTContext &Context, const VarDecl *VD) { - // Everything located semantically within an anonymous namespace is - // always internal. - if (VD->isInAnonymousNamespace()) + // If this is a static data member, compute the kind of template + // specialization. Otherwise, this variable is not part of a + // template. + TemplateSpecializationKind TSK = TSK_Undeclared; + if (VD->isStaticDataMember()) + TSK = VD->getTemplateSpecializationKind(); + + Linkage L = VD->getLinkage(); + if (L == ExternalLinkage && Context.getLangOptions().CPlusPlus && + VD->getType()->getLinkage() == UniqueExternalLinkage) + L = UniqueExternalLinkage; + + switch (L) { + case NoLinkage: + case InternalLinkage: + case UniqueExternalLinkage: return CodeGenModule::GVA_Internal; - // Handle linkage for static data members. - if (VD->isStaticDataMember()) { - switch (VD->getTemplateSpecializationKind()) { + case ExternalLinkage: + switch (TSK) { case TSK_Undeclared: case TSK_ExplicitSpecialization: + + // FIXME: ExplicitInstantiationDefinition should be weak! case TSK_ExplicitInstantiationDefinition: return CodeGenModule::GVA_StrongExternal; @@ -959,22 +982,26 @@ GetLinkageForVariable(ASTContext &Context, const VarDecl *VD) { // Fall through to treat this like any other instantiation. case TSK_ImplicitInstantiation: - return CodeGenModule::GVA_TemplateInstantiation; + return CodeGenModule::GVA_TemplateInstantiation; } } - if (VD->getLinkage() == VarDecl::InternalLinkage) - return CodeGenModule::GVA_Internal; - return CodeGenModule::GVA_StrongExternal; } +CharUnits CodeGenModule::GetTargetTypeStoreSize(const llvm::Type *Ty) const { + return CharUnits::fromQuantity( + TheTargetData.getTypeStoreSizeInBits(Ty) / Context.getCharWidth()); +} + void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { llvm::Constant *Init = 0; QualType ASTTy = D->getType(); bool NonConstInit = false; - if (D->getInit() == 0) { + const Expr *InitExpr = D->getAnyInitializer(); + + if (!InitExpr) { // This is a tentative definition; tentative definitions are // implicitly initialized with { 0 }. // @@ -987,10 +1014,10 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { assert(!ASTTy->isIncompleteType() && "Unexpected incomplete type"); Init = EmitNullConstant(D->getType()); } else { - Init = EmitConstantExpr(D->getInit(), D->getType()); + Init = EmitConstantExpr(InitExpr, D->getType()); if (!Init) { - QualType T = D->getInit()->getType(); + QualType T = InitExpr->getType(); if (getLangOptions().CPlusPlus) { EmitCXXGlobalVarDeclInitFunc(D); Init = EmitNullConstant(T); @@ -1058,7 +1085,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { if (!NonConstInit && DeclIsConstantGlobal(Context, D)) GV->setConstant(true); - GV->setAlignment(getContext().getDeclAlignInBytes(D)); + GV->setAlignment(getContext().getDeclAlign(D).getQuantity()); // Set the llvm linkage type as appropriate. GVALinkage Linkage = GetLinkageForVariable(getContext(), D); @@ -1256,8 +1283,8 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) { 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).getNameStart(); + const char *AliaseeName = + getContext().Idents.get(AA->getAliasee()).getNameStart(); // Create a reference to the named value. This ensures that it is emitted // if a deferred decl. @@ -1473,11 +1500,9 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { // String pointer. llvm::Constant *C = llvm::ConstantArray::get(VMContext, Entry.getKey().str()); - const char *Sect = 0; llvm::GlobalValue::LinkageTypes Linkage; bool isConstant; if (isUTF16) { - Sect = getContext().Target.getUnicodeStringSection(); // 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 @@ -1491,11 +1516,9 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { 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); + CharUnits Align = getContext().getTypeAlignInChars(getContext().ShortTy); + GV->setAlignment(Align.getQuantity()); } Fields[2] = llvm::ConstantExpr::getGetElementPtr(GV, Zeros, 2); |