diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Decl.cpp | 390 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 161 | ||||
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 10 | ||||
-rw-r--r-- | lib/CodeGen/CGRTTI.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 75 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 5 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 12 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 2 |
9 files changed, 382 insertions, 277 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 5a1edbd0e6..fc5b57f148 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -32,35 +32,53 @@ using namespace clang; // NamedDecl Implementation //===----------------------------------------------------------------------===// +static Visibility GetVisibilityFromAttr(const VisibilityAttr *A) { + switch (A->getVisibility()) { + case VisibilityAttr::Default: + return DefaultVisibility; + case VisibilityAttr::Hidden: + return HiddenVisibility; + case VisibilityAttr::Protected: + return ProtectedVisibility; + } + return DefaultVisibility; +} + +typedef std::pair<Linkage,Visibility> LVPair; +static LVPair merge(LVPair L, LVPair R) { + return LVPair(minLinkage(L.first, R.first), + minVisibility(L.second, R.second)); +} + /// \brief Get the most restrictive linkage for the types in the given /// template parameter list. -static Linkage -getLinkageForTemplateParameterList(const TemplateParameterList *Params) { - Linkage L = ExternalLinkage; +static LVPair +getLVForTemplateParameterList(const TemplateParameterList *Params) { + LVPair LV(ExternalLinkage, DefaultVisibility); for (TemplateParameterList::const_iterator P = Params->begin(), PEnd = Params->end(); P != PEnd; ++P) { if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) if (!NTTP->getType()->isDependentType()) { - L = minLinkage(L, NTTP->getType()->getLinkage()); + LV = merge(LV, NTTP->getType()->getLinkageAndVisibility()); continue; } if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P)) { - L = minLinkage(L, - getLinkageForTemplateParameterList(TTP->getTemplateParameters())); + LV = + merge(LV, getLVForTemplateParameterList(TTP->getTemplateParameters())); } } - return L; + return LV; } /// \brief Get the most restrictive linkage for the types and /// declarations in the given template argument list. -static Linkage getLinkageForTemplateArgumentList(const TemplateArgument *Args, - unsigned NumArgs) { - Linkage L = ExternalLinkage; +static LVPair getLVForTemplateArgumentList(const TemplateArgument *Args, + unsigned NumArgs) { + LVPair LV(ExternalLinkage, DefaultVisibility); for (unsigned I = 0; I != NumArgs; ++I) { switch (Args[I].getKind()) { @@ -70,40 +88,41 @@ static Linkage getLinkageForTemplateArgumentList(const TemplateArgument *Args, break; case TemplateArgument::Type: - L = minLinkage(L, Args[I].getAsType()->getLinkage()); + LV = merge(LV, Args[I].getAsType()->getLinkageAndVisibility()); break; case TemplateArgument::Declaration: - if (NamedDecl *ND = dyn_cast<NamedDecl>(Args[I].getAsDecl())) - L = minLinkage(L, ND->getLinkage()); - if (ValueDecl *VD = dyn_cast<ValueDecl>(Args[I].getAsDecl())) - L = minLinkage(L, VD->getType()->getLinkage()); + // The decl can validly be null as the representation of nullptr + // arguments, valid only in C++0x. + if (Decl *D = Args[I].getAsDecl()) { + if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) + LV = merge(LV, ND->getLinkageAndVisibility()); + if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) + LV = merge(LV, VD->getType()->getLinkageAndVisibility()); + } break; case TemplateArgument::Template: - if (TemplateDecl *Template - = Args[I].getAsTemplate().getAsTemplateDecl()) - L = minLinkage(L, Template->getLinkage()); + if (TemplateDecl *Template = Args[I].getAsTemplate().getAsTemplateDecl()) + LV = merge(LV, Template->getLinkageAndVisibility()); break; case TemplateArgument::Pack: - L = minLinkage(L, - getLinkageForTemplateArgumentList(Args[I].pack_begin(), - Args[I].pack_size())); + LV = merge(LV, getLVForTemplateArgumentList(Args[I].pack_begin(), + Args[I].pack_size())); break; } } - return L; + return LV; } -static Linkage -getLinkageForTemplateArgumentList(const TemplateArgumentList &TArgs) { - return getLinkageForTemplateArgumentList(TArgs.getFlatArgumentList(), - TArgs.flat_size()); +static LVPair getLVForTemplateArgumentList(const TemplateArgumentList &TArgs) { + return getLVForTemplateArgumentList(TArgs.getFlatArgumentList(), + TArgs.flat_size()); } -static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { +static LVPair getLVForNamespaceScopeDecl(const NamedDecl *D) { assert(D->getDeclContext()->getRedeclContext()->isFileContext() && "Not a name having namespace scope"); ASTContext &Context = D->getASTContext(); @@ -117,7 +136,7 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { if (const VarDecl *Var = dyn_cast<VarDecl>(D)) { // Explicitly declared static. if (Var->getStorageClass() == SC_Static) - return InternalLinkage; + return LVPair(InternalLinkage, DefaultVisibility); // - an object or reference that is explicitly declared const // and neither explicitly declared extern nor previously @@ -135,7 +154,7 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { FoundExtern = true; if (!FoundExtern) - return InternalLinkage; + return LVPair(InternalLinkage, DefaultVisibility); } } else if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) { // C++ [temp]p4: @@ -150,23 +169,63 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { // Explicitly declared static. if (Function->getStorageClass() == SC_Static) - return InternalLinkage; + return LVPair(InternalLinkage, DefaultVisibility); } else if (const FieldDecl *Field = dyn_cast<FieldDecl>(D)) { // - a data member of an anonymous union. if (cast<RecordDecl>(Field->getDeclContext())->isAnonymousStructOrUnion()) - return InternalLinkage; + return LVPair(InternalLinkage, DefaultVisibility); } + if (D->isInAnonymousNamespace()) + return LVPair(UniqueExternalLinkage, DefaultVisibility); + + // Set up the defaults. + + // C99 6.2.2p5: + // If the declaration of an identifier for an object has file + // scope and no storage-class specifier, its linkage is + // external. + LVPair LV(ExternalLinkage, DefaultVisibility); + + // We ignore -fvisibility on non-definitions and explicit + // instantiation declarations. + bool ConsiderDashFVisibility = true; + // C++ [basic.link]p4: - + // A name having namespace scope has external linkage if it is the // name of // // - an object or reference, unless it has internal linkage; or if (const VarDecl *Var = dyn_cast<VarDecl>(D)) { + // Modify the variable's LV by the LV of its type unless this is + // C or extern "C". This follows from [basic.link]p9: + // A type without linkage shall not be used as the type of a + // variable or function with external linkage unless + // - the entity has C language linkage, or + // - the entity is declared within an unnamed namespace, or + // - the entity is not used or is defined in the same + // translation unit. + // and [basic.link]p10: + // ...the types specified by all declarations referring to a + // given variable or function shall be identical... + // C does not have an equivalent rule. + // + // Note that we don't want to make the variable non-external + // because of this, but unique-external linkage suits us. + if (Context.getLangOptions().CPlusPlus && !Var->isExternC()) { + LVPair TypeLV = Var->getType()->getLinkageAndVisibility(); + if (TypeLV.first != ExternalLinkage) + return LVPair(UniqueExternalLinkage, DefaultVisibility); + LV.second = minVisibility(LV.second, TypeLV.second); + } + if (!Context.getLangOptions().CPlusPlus && (Var->getStorageClass() == SC_Extern || Var->getStorageClass() == SC_PrivateExtern)) { + if (Var->getStorageClass() == SC_PrivateExtern) + LV.second = HiddenVisibility; + // C99 6.2.2p4: // For an identifier declared with the storage-class specifier // extern in a scope in which a prior declaration of that @@ -177,23 +236,23 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { // is visible, or if the prior declaration specifies no // linkage, then the identifier has external linkage. if (const VarDecl *PrevVar = Var->getPreviousDeclaration()) { - if (Linkage L = PrevVar->getLinkage()) - return L; + LVPair PrevLV = PrevVar->getLinkageAndVisibility(); + if (PrevLV.first) LV.first = PrevLV.first; + LV.second = minVisibility(LV.second, PrevLV.second); } } - // C99 6.2.2p5: - // If the declaration of an identifier for an object has file - // scope and no storage-class specifier, its linkage is - // external. - if (Var->isInAnonymousNamespace()) - return UniqueExternalLinkage; - - return ExternalLinkage; - } - // - a function, unless it has internal linkage; or - if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { + } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { + // Modify the function's LV by the LV of its type unless this is + // C or extern "C". See the comment above about variables. + if (Context.getLangOptions().CPlusPlus && !Function->isExternC()) { + LVPair TypeLV = Function->getType()->getLinkageAndVisibility(); + if (TypeLV.first != ExternalLinkage) + return LVPair(UniqueExternalLinkage, DefaultVisibility); + LV.second = minVisibility(LV.second, TypeLV.second); + } + // C99 6.2.2p5: // If the declaration of an identifier for a function has no // storage-class specifier, its linkage is determined exactly @@ -213,24 +272,25 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { // is visible, or if the prior declaration specifies no // linkage, then the identifier has external linkage. if (const FunctionDecl *PrevFunc = Function->getPreviousDeclaration()) { - if (Linkage L = PrevFunc->getLinkage()) - return L; + LVPair PrevLV = PrevFunc->getLinkageAndVisibility(); + if (PrevLV.first) LV.first = PrevLV.first; + LV.second = minVisibility(LV.second, PrevLV.second); } } - if (Function->isInAnonymousNamespace()) - return UniqueExternalLinkage; - if (FunctionTemplateSpecializationInfo *SpecInfo = Function->getTemplateSpecializationInfo()) { - Linkage L = SpecInfo->getTemplate()->getLinkage(); + LV = merge(LV, SpecInfo->getTemplate()->getLinkageAndVisibility()); const TemplateArgumentList &TemplateArgs = *SpecInfo->TemplateArguments; - L = minLinkage(L, getLinkageForTemplateArgumentList(TemplateArgs)); - return L; + LV = merge(LV, getLVForTemplateArgumentList(TemplateArgs)); + + if (SpecInfo->getTemplateSpecializationKind() + == TSK_ExplicitInstantiationDeclaration) + ConsiderDashFVisibility = false; } - return ExternalLinkage; - } + if (ConsiderDashFVisibility) + ConsiderDashFVisibility = Function->hasBody(); // - a named class (Clause 9), or an unnamed class defined in a // typedef declaration in which the class has the typedef name @@ -238,116 +298,180 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { // - a named enumeration (7.2), or an unnamed enumeration // defined in a typedef declaration in which the enumeration // has the typedef name for linkage purposes (7.1.3); or - if (const TagDecl *Tag = dyn_cast<TagDecl>(D)) - if (Tag->getDeclName() || Tag->getTypedefForAnonDecl()) { - if (Tag->isInAnonymousNamespace()) - return UniqueExternalLinkage; - - // If this is a class template specialization, consider the - // linkage of the template and template arguments. - if (const ClassTemplateSpecializationDecl *Spec - = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) { - const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); - Linkage L = getLinkageForTemplateArgumentList(TemplateArgs); - return minLinkage(L, Spec->getSpecializedTemplate()->getLinkage()); - } + } else if (const TagDecl *Tag = dyn_cast<TagDecl>(D)) { + // Unnamed tags have no linkage. + if (!Tag->getDeclName() && !Tag->getTypedefForAnonDecl()) + return LVPair(NoLinkage, DefaultVisibility); - return ExternalLinkage; + // If this is a class template specialization, consider the + // linkage of the template and template arguments. + if (const ClassTemplateSpecializationDecl *Spec + = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) { + // From the template. Note below the restrictions on how we + // compute template visibility. + LV = merge(LV, Spec->getSpecializedTemplate()->getLinkageAndVisibility()); + + // The arguments at which the template was instantiated. + const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); + LV = merge(LV, getLVForTemplateArgumentList(TemplateArgs)); + + if (Spec->getTemplateSpecializationKind() + == TSK_ExplicitInstantiationDeclaration) + ConsiderDashFVisibility = false; } + if (ConsiderDashFVisibility) + ConsiderDashFVisibility = Tag->isDefinition(); + // - an enumerator belonging to an enumeration with external linkage; - if (isa<EnumConstantDecl>(D)) { - Linkage L = cast<NamedDecl>(D->getDeclContext())->getLinkage(); - if (isExternalLinkage(L)) - return L; - } + } else if (isa<EnumConstantDecl>(D)) { + LVPair EnumLV = + cast<NamedDecl>(D->getDeclContext())->getLinkageAndVisibility(); + if (!isExternalLinkage(EnumLV.first)) + return LVPair(NoLinkage, DefaultVisibility); + LV = merge(LV, EnumLV); // - a template, unless it is a function template that has // internal linkage (Clause 14); - if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) { - if (D->isInAnonymousNamespace()) - return UniqueExternalLinkage; + } else if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) { + LV = merge(LV, getLVForTemplateParameterList( + Template->getTemplateParameters())); - return getLinkageForTemplateParameterList( - Template->getTemplateParameters()); - } + // We do not want to consider attributes or global settings when + // computing template visibility. + return LV; // - a namespace (7.3), unless it is declared within an unnamed // namespace. - if (isa<NamespaceDecl>(D) && !D->isInAnonymousNamespace()) - return ExternalLinkage; + } else if (isa<NamespaceDecl>(D) && !D->isInAnonymousNamespace()) { + return LV; - return NoLinkage; + // By extension, we assign external linkage to Objective-C + // interfaces. + } else if (isa<ObjCInterfaceDecl>(D)) { + // fallout + + // Everything not covered here has no linkage. + } else { + return LVPair(NoLinkage, DefaultVisibility); + } + + // If we ended up with non-external linkage, visibility should + // always be default. + if (LV.first != ExternalLinkage) + return LVPair(LV.first, DefaultVisibility); + + // If we didn't end up with hidden visibility, consider attributes + // and -fvisibility. + if (LV.second != HiddenVisibility) { + Visibility StandardV; + + // If we have an explicit visibility attribute, merge that in. + const VisibilityAttr *VA = D->getAttr<VisibilityAttr>(); + if (VA) + StandardV = GetVisibilityFromAttr(VA); + else if (ConsiderDashFVisibility) + StandardV = Context.getLangOptions().getVisibilityMode(); + else + StandardV = DefaultVisibility; // no-op + + LV.second = minVisibility(LV.second, StandardV); + } + + return LV; } -static Linkage getLinkageForClassMember(const NamedDecl *D) { +static LVPair getLVForClassMember(const NamedDecl *D) { + // Only certain class members have linkage. Note that fields don't + // really have linkage, but it's convenient to say they do for the + // purposes of calculating linkage of pointer-to-data-member + // template arguments. if (!(isa<CXXMethodDecl>(D) || isa<VarDecl>(D) || + isa<FieldDecl>(D) || (isa<TagDecl>(D) && (D->getDeclName() || cast<TagDecl>(D)->getTypedefForAnonDecl())))) - return NoLinkage; + return LVPair(NoLinkage, DefaultVisibility); // Class members only have linkage if their class has external linkage. - Linkage L = cast<RecordDecl>(D->getDeclContext())->getLinkage(); - if (!isExternalLinkage(L)) return NoLinkage; + LVPair ClassLV = + cast<RecordDecl>(D->getDeclContext())->getLinkageAndVisibility(); + if (!isExternalLinkage(ClassLV.first)) + return LVPair(NoLinkage, DefaultVisibility); // If the class already has unique-external linkage, we can't improve. - if (L == UniqueExternalLinkage) return UniqueExternalLinkage; + if (ClassLV.first == UniqueExternalLinkage) + return LVPair(UniqueExternalLinkage, DefaultVisibility); + + // Start with the class's linkage and visibility. + LVPair LV = ClassLV; + + // If we have an explicit visibility attribute, merge that in. + const VisibilityAttr *VA = D->getAttr<VisibilityAttr>(); + if (VA) LV.second = minVisibility(LV.second, GetVisibilityFromAttr(VA)); + + // If it's a value declaration, apply the LV from its type. + // See the comment about namespace-scope variable decls above. + if (isa<ValueDecl>(D)) { + LVPair TypeLV = cast<ValueDecl>(D)->getType()->getLinkageAndVisibility(); + if (TypeLV.first != ExternalLinkage) + LV.first = minLinkage(LV.first, UniqueExternalLinkage); + LV.second = minVisibility(LV.second, TypeLV.second); + } - // If this is a method template specialization, use the linkage for - // the template parameters and arguments. if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { - if (FunctionTemplateSpecializationInfo *SpecInfo + // If this is a method template specialization, use the linkage for + // the template parameters and arguments. + if (FunctionTemplateSpecializationInfo *Spec = MD->getTemplateSpecializationInfo()) { - Linkage ArgLinkage = - getLinkageForTemplateArgumentList(*SpecInfo->TemplateArguments); - Linkage ParamLinkage = - getLinkageForTemplateParameterList( - SpecInfo->getTemplate()->getTemplateParameters()); - return minLinkage(ArgLinkage, ParamLinkage); + LV = merge(LV, getLVForTemplateArgumentList(*Spec->TemplateArguments)); + LV = merge(LV, getLVForTemplateParameterList( + Spec->getTemplate()->getTemplateParameters())); } + // If -fvisibility-inlines-hidden was provided, then inline C++ + // member functions get "hidden" visibility if they don't have an + // explicit visibility attribute. + if (!VA && MD->isInlined() && LV.second > HiddenVisibility && + D->getASTContext().getLangOptions().InlineVisibilityHidden) + LV.second = HiddenVisibility; + // Similarly for member class template specializations. } else if (const ClassTemplateSpecializationDecl *Spec = dyn_cast<ClassTemplateSpecializationDecl>(D)) { - Linkage ArgLinkage = - getLinkageForTemplateArgumentList(Spec->getTemplateArgs()); - Linkage ParamLinkage = - getLinkageForTemplateParameterList( - Spec->getSpecializedTemplate()->getTemplateParameters()); - return minLinkage(ArgLinkage, ParamLinkage); + LV = merge(LV, getLVForTemplateArgumentList(Spec->getTemplateArgs())); + LV = merge(LV, getLVForTemplateParameterList( + Spec->getSpecializedTemplate()->getTemplateParameters())); } - return ExternalLinkage; + return LV; } -Linkage NamedDecl::getLinkage() const { +LVPair NamedDecl::getLinkageAndVisibility() const { // Objective-C: treat all Objective-C declarations as having external // linkage. switch (getKind()) { default: break; + case Decl::TemplateTemplateParm: // count these as external + case Decl::NonTypeTemplateParm: case Decl::ObjCAtDefsField: case Decl::ObjCCategory: case Decl::ObjCCategoryImpl: - case Decl::ObjCClass: case Decl::ObjCCompatibleAlias: case Decl::ObjCForwardProtocol: case Decl::ObjCImplementation: - case Decl::ObjCInterface: - case Decl::ObjCIvar: case Decl::ObjCMethod: case Decl::ObjCProperty: case Decl::ObjCPropertyImpl: case Decl::ObjCProtocol: - return ExternalLinkage; + return LVPair(ExternalLinkage, DefaultVisibility); } // Handle linkage for namespace-scope names. if (getDeclContext()->getRedeclContext()->isFileContext()) - if (Linkage L = getLinkageForNamespaceScopeDecl(this)) - return L; + return getLVForNamespaceScopeDecl(this); // C++ [basic.link]p5: // In addition, a member function, static data member, a named @@ -357,7 +481,7 @@ Linkage NamedDecl::getLinkage() const { // purposes (7.1.3), has external linkage if the name of the class // has external linkage. if (getDeclContext()->isRecord()) - return getLinkageForClassMember(this); + return getLVForClassMember(this); // C++ [basic.link]p6: // The name of a function declared in block scope and the name of @@ -372,34 +496,48 @@ Linkage NamedDecl::getLinkage() const { // external linkage. if (getLexicalDeclContext()->isFunctionOrMethod()) { if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this)) { - if (Function->getPreviousDeclaration()) - if (Linkage L = Function->getPreviousDeclaration()->getLinkage()) - return L; - if (Function->isInAnonymousNamespace()) - return UniqueExternalLinkage; + return LVPair(UniqueExternalLinkage, DefaultVisibility); + + LVPair LV(ExternalLinkage, DefaultVisibility); + if (const VisibilityAttr *VA = Function->getAttr<VisibilityAttr>()) + LV.second = GetVisibilityFromAttr(VA); - return ExternalLinkage; + if (const FunctionDecl *Prev = Function->getPreviousDeclaration()) { + LVPair PrevLV = Prev->getLinkageAndVisibility(); + if (PrevLV.first) LV.first = PrevLV.first; + LV.second = minVisibility(LV.second, PrevLV.second); + } + + return LV; } if (const VarDecl *Var = dyn_cast<VarDecl>(this)) if (Var->getStorageClass() == SC_Extern || Var->getStorageClass() == SC_PrivateExtern) { - if (Var->getPreviousDeclaration()) - if (Linkage L = Var->getPreviousDeclaration()->getLinkage()) - return L; - if (Var->isInAnonymousNamespace()) - return UniqueExternalLinkage; + return LVPair(UniqueExternalLinkage, DefaultVisibility); + + LVPair LV(ExternalLinkage, DefaultVisibility); + if (Var->getStorageClass() == SC_PrivateExtern) + LV.second = HiddenVisibility; + else if (const VisibilityAttr *VA = Var->getAttr<VisibilityAttr>()) + LV.second = GetVisibilityFromAttr(VA); + + if (const VarDecl *Prev = Var->getPreviousDeclaration()) { + LVPair PrevLV = Prev->getLinkageAndVisibility(); + if (PrevLV.first) LV.first = PrevLV.first; + LV.second = minVisibility(LV.second, PrevLV.second); + } - return ExternalLinkage; + return LV; } } // C++ [basic.link]p6: // Names not covered by these rules have no linkage. - return NoLinkage; - } + return LVPair(NoLinkage, DefaultVisibility); +} std::string NamedDecl::getQualifiedNameAsString() const { return getQualifiedNameAsString(getASTContext().getLangOptions()); diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 145250793f..33aac123c2 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -1268,129 +1268,154 @@ void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getBaseType(), qual_begin(), getNumProtocols()); } +void Type::ensureCachedProperties() const { + if (!TypeBits.isCacheValid()) { + CachedProperties Result = getCachedProperties(); + TypeBits.CacheValidAndVisibility = Result.getVisibility() + 1U; + assert(TypeBits.isCacheValid() && + TypeBits.getVisibility() == Result.getVisibility()); + TypeBits.CachedLinkage = Result.getLinkage(); + TypeBits.CachedLocalOrUnnamed = Result.hasLocalOrUnnamedType(); + } +} + /// \brief Determine the linkage of this type. Linkage Type::getLinkage() const { if (this != CanonicalType.getTypePtr()) return CanonicalType->getLinkage(); - - if (!TypeBits.LinkageKnown) { - std::pair<Linkage, bool> Result = getLinkageUnnamedLocalImpl(); - TypeBits.CachedLinkage = Result.first; - TypeBits.CachedLocalOrUnnamed = Result.second; - TypeBits.LinkageKnown = true; - } - - return static_cast<clang::Linkage>(TypeBits.CachedLinkage); + + ensureCachedProperties(); + return TypeBits.getLinkage(); +} + +/// \brief Determine the linkage of this type. +Visibility Type::getVisibility() const { + if (this != CanonicalType.getTypePtr()) + return CanonicalType->getVisibility(); + + ensureCachedProperties(); + return TypeBits.getVisibility(); } bool Type::hasUnnamedOrLocalType() const { if (this != CanonicalType.getTypePtr()) return CanonicalType->hasUnnamedOrLocalType(); - - if (!TypeBits.LinkageKnown) { - std::pair<Linkage, bool> Result = getLinkageUnnamedLocalImpl(); - TypeBits.CachedLinkage = Result.first; - TypeBits.CachedLocalOrUnnamed = Result.second; - TypeBits.LinkageKnown = true; - } - - return TypeBits.CachedLocalOrUnnamed; + + ensureCachedProperties(); + return TypeBits.hasLocalOrUnnamedType(); } -std::pair<Linkage, bool> Type::getLinkageUnnamedLocalImpl() const { - // C++ [basic.link]p8: - // Names not covered by these rules have no linkage. - return std::make_pair(NoLinkage, false); +std::pair<Linkage,Visibility> Type::getLinkageAndVisibility() const { + if (this != CanonicalType.getTypePtr()) + return CanonicalType->getLinkageAndVisibility(); + + ensureCachedProperties(); + return std::make_pair(TypeBits.getLinkage(), TypeBits.getVisibility()); +} + + +Type::CachedProperties Type::getCachedProperties(const Type *T) { + T = T->CanonicalType.getTypePtr(); + T->ensureCachedProperties(); + return CachedProperties(T->TypeBits.getLinkage(), + T->TypeBits.getVisibility(), + T->TypeBits.hasLocalOrUnnamedType()); } void Type::ClearLinkageCache() { if (this != CanonicalType.getTypePtr()) CanonicalType->ClearLinkageCache(); else - TypeBits.LinkageKnown = false; + TypeBits.CacheValidAndVisibility = 0; } -std::pair<Linkage, bool> BuiltinType::getLinkageUnnamedLocalImpl() const { +Type::CachedProperties Type::getCachedProperties() const { + // Treat dependent types as external. + if (isDependentType()) + return CachedProperties(ExternalLinkage, DefaultVisibility, false); + + // C++ [basic.link]p8: + // Names not covered by these rules have no linkage. + return CachedProperties(NoLinkage, DefaultVisibility, false); +} + +Type::CachedProperties BuiltinType::getCachedProperties() const { // C++ [basic.link]p8: // A type is said to have linkage if and only if: // - it is a fundamental type (3.9.1); or - return std::make_pair(ExternalLinkage, false); + return CachedProperties(ExternalLinkage, DefaultVisibility, false); } -std::pair<Linkage, bool> TagType::getLinkageUnnamedLocalImpl() const { +Type::CachedProperties TagType::getCachedProperties() const { // C++ [basic.link]p8: // - it is a class or enumeration type that is named (or has a name for // linkage purposes (7.1.3)) and the name has linkage; or // - it is a specialization of a class template (14); or - return std::make_pair(getDecl()->getLinkage(), - getDecl()->getDeclContext()->isFunctionOrMethod() || + + std::pair<Linkage,Visibility> LV = getDecl()->getLinkageAndVisibility(); + bool IsLocalOrUnnamed = + getDecl()->getDeclContext()->isFunctionOrMethod() || (!getDecl()->getIdentifier() && - !getDecl()->getTypedefForAnonDecl())); + !getDecl()->getTypedefForAnonDecl()); + return CachedProperties(LV.first, LV.second, IsLocalOrUnnamed); } // C++ [basic.link]p8: // - it is a compound type (3.9.2) other than a class or enumeration, // compounded exclusively from types that have linkage; or -std::pair<Linkage, bool> ComplexType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(ElementType->getLinkage(), - ElementType->hasUnnamedOrLocalType()); +Type::CachedProperties ComplexType::getCachedProperties() const { + return Type::getCachedProperties(ElementType); } -std::pair<Linkage, bool> PointerType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(PointeeType->getLinkage(), - PointeeType->hasUnnamedOrLocalType()); +Type::CachedProperties PointerType::getCachedProperties() const { + return Type::getCachedProperties(PointeeType); } -std::pair<Linkage, bool> BlockPointerType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(PointeeType->getLinkage(), - PointeeType->hasUnnamedOrLocalType()); +Type::CachedProperties BlockPointerType::getCachedProperties() const { + return Type::getCachedProperties(PointeeType); } -std::pair<Linkage, bool> ReferenceType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(PointeeType->getLinkage(), - PointeeType->hasUnnamedOrLocalType()); +Type::CachedProperties ReferenceType::getCachedProperties() const { + return Type::getCachedProperties(PointeeType); } -std::pair<Linkage, bool> MemberPointerType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(minLinkage(Class->getLinkage(), - PointeeType->getLinkage()), - Class->hasUnnamedOrLocalType() || - PointeeType->hasUnnamedOrLocalType()); +Type::CachedProperties MemberPointerType::getCachedProperties() const { + return merge(Type::getCachedProperties(Class), + Type::getCachedProperties(PointeeType)); } -std::pair<Linkage, bool> ArrayType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(ElementType->getLinkage(), - ElementType->hasUnnamedOrLocalType()); +Type::CachedProperties ArrayType::getCachedProperties() const { + return Type::getCachedProperties(ElementType); } -std::pair<Linkage, bool> VectorType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(ElementType->getLinkage(), - ElementType->hasUnnamedOrLocalType()); +Type::CachedProperties VectorType::getCachedProperties() const { + return Type::getCachedProperties(ElementType); } -std::pair<Linkage, bool> -FunctionNoProtoType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(getResultType()->getLinkage(), - getResultType()->hasUnnamedOrLocalType()); +Type::CachedProperties FunctionNoProtoType::getCachedProperties() const { + return Type::getCachedProperties(getResultType()); } -std::pair<Linkage, bool> FunctionProtoType::getLinkageUnnamedLocalImpl() const { - Linkage L = getResultType()->getLinkage(); - bool UnnamedOrLocal = getResultType()->hasUnnamedOrLocalType(); +Type::CachedProperties FunctionProtoType::getCachedProperties() const { + CachedProperties Cached = Type::getCachedProperties(getResultType()); for (arg_type_iterator A = arg_type_begin(), AEnd = arg_type_end(); A != AEnd; ++A) { - L = minLinkage(L, (*A)->getLinkage()); - UnnamedOrLocal = UnnamedOrLocal || (*A)->hasUnnamedOrLocalType(); + Cached = merge(Cached, Type::getCachedProperties(*A)); } - - return std::make_pair(L, UnnamedOrLocal); + return Cached; +} + +Type::CachedProperties ObjCInterfaceType::getCachedProperties() const { + std::pair<Linkage,Visibility> LV = getDecl()->getLinkageAndVisibility(); + return CachedProperties(LV.first, LV.second, false); } -std::pair<Linkage, bool> ObjCObjectType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(ExternalLinkage, false); +Type::CachedProperties ObjCObjectType::getCachedProperties() const { + if (const ObjCInterfaceType *T = getBaseType()->getAs<ObjCInterfaceType>()) + return Type::getCachedProperties(T); + return CachedProperties(ExternalLinkage, DefaultVisibility, false); } -std::pair<Linkage, bool> -ObjCObjectPointerType::getLinkageUnnamedLocalImpl() const { - return std::make_pair(ExternalLinkage, false); +Type::CachedProperties ObjCObjectPointerType::getCachedProperties() const { + return Type::getCachedProperties(PointeeType); } diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 961233aab6..02cd8f89a2 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -180,7 +180,7 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl, } // Finally, set up the alias with its proper name and attributes. - SetCommonAttributes(AliasDecl.getDecl(), Alias); + SetCommonAttributes(cast<NamedDecl>(AliasDecl.getDecl()), Alias); return false; } diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 9ed3733a66..098157474b 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -2197,7 +2197,7 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { CGM.getContext().getASTObjCImplementationLayout(ID).getSize() / 8; // FIXME: Set CXX-structors flag. - if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden) + if (ID->getClassInterface()->getVisibility() == HiddenVisibility) Flags |= eClassFlags_Hidden; std::vector<llvm::Constant*> InstanceMethods, ClassMethods; @@ -2282,7 +2282,7 @@ llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, unsigned Flags = eClassFlags_Meta; unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy); - if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden) + if (ID->getClassInterface()->getVisibility() == HiddenVisibility) Flags |= eClassFlags_Hidden; std::vector<llvm::Constant*> Values(12); @@ -4968,7 +4968,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { llvm::GlobalVariable *SuperClassGV, *IsAGV; bool classIsHidden = - CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden; + ID->getClassInterface()->getVisibility() == HiddenVisibility; if (classIsHidden) flags |= OBJC2_CLS_HIDDEN; if (ID->getNumIvarInitializers()) @@ -5263,7 +5263,7 @@ CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, // well (i.e., in ObjCIvarOffsetVariable). if (Ivar->getAccessControl() == ObjCIvarDecl::Private || Ivar->getAccessControl() == ObjCIvarDecl::Package || - CGM.getDeclVisibilityMode(ID) == LangOptions::Hidden) + ID->getVisibility() == HiddenVisibility) IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); else IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility); @@ -6237,7 +6237,7 @@ CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID, ID-&g |