diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index c5a34716f918..019682d09320 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -796,12 +796,16 @@ private: /// \brief Whether this type is a variably-modified type (C99 6.7.5). bool VariablyModified : 1; - /// \brief Whether the linkage of this type is already known. + /// \brief Whether the linkage of this type along with the presence of any + /// local or unnamed types is already known. mutable bool LinkageKnown : 1; /// \brief Linkage of this type. mutable unsigned CachedLinkage : 2; + /// \brief Whether this type involves and local or unnamed types. + mutable bool CachedLocalOrUnnamed : 1; + /// \brief FromAST - Whether this type comes from an AST file. mutable bool FromAST : 1; @@ -813,7 +817,7 @@ private: protected: /// \brief Compute the linkage of this type along with the presence of /// any local or unnamed types. - virtual Linkage getLinkageImpl() const; + virtual std::pair getLinkageUnnamedLocalImpl() const; enum { BitsRemainingInType = 19 }; @@ -959,6 +963,9 @@ public: /// \brief Whether this type is a variably-modified type (C99 6.7.5). bool isVariablyModifiedType() const { return VariablyModified; } + /// \brief Whether this type is or contains a local or unnamed type. + bool hasUnnamedOrLocalType() const; + bool isOverloadableType() const; /// \brief Determine wither this type is a C++ elaborated-type-specifier. @@ -1146,7 +1153,7 @@ private: Kind TypeKind; protected: - virtual Linkage getLinkageImpl() const; + virtual std::pair getLinkageUnnamedLocalImpl() const; public: BuiltinType(Kind K) @@ -1201,7 +1208,7 @@ class ComplexType : public Type, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these. protected: - virtual Linkage getLinkageImpl() const; + virtual std::pair getLinkageUnnamedLocalImpl() const; public: QualType getElementType() const { return ElementType; } @@ -1233,7 +1240,7 @@ class PointerType : public Type, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these. protected: - virtual Linkage getLinkageImpl() const; + virtual std::pair getLinkageUnnamedLocalImpl() const; public: @@ -1267,7 +1274,7 @@ class BlockPointerType : public Type, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these. protected: - virtual Linkage getLinkageImpl() const; + virtual std::pair getLinkageUnnamedLocalImpl() const; public: @@ -1321,7 +1328,7 @@ protected: InnerRef(Referencee->isReferenceType()) { } - virtual Linkage getLinkageImpl() const; + virtual std::pair getLinkageUnnamedLocalImpl() const; public: bool isSpelledAsLValue() const { return SpelledAsLValue; } @@ -1405,7 +1412,7 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these. protected: - virtual Linkage getLinkageImpl() const; + virtual std::pair getLinkageUnnamedLocalImpl() const; public: QualType getPointeeType() const { return PointeeType; } @@ -1479,7 +1486,7 @@ protected: friend class ASTContext; // ASTContext creates these. - virtual Linkage getLinkageImpl() const; + virtual std::pair getLinkageUnnamedLocalImpl() const; public: QualType getElementType() const { return ElementType; } @@ -1782,7 +1789,7 @@ protected: NumElements(nElements), AltiVecSpec(altiVecSpec) {} friend class ASTContext; // ASTContext creates these. - virtual Linkage getLinkageImpl() const; + virtual std::pair getLinkageUnnamedLocalImpl() const; public: @@ -2023,7 +2030,7 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these. protected: - virtual Linkage getLinkageImpl() const; + virtual std::pair getLinkageUnnamedLocalImpl() const; public: // No additional state past what FunctionType provides. @@ -2081,7 +2088,7 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these. protected: - virtual Linkage getLinkageImpl() const; + virtual std::pair getLinkageUnnamedLocalImpl() const; public: unsigned getNumArgs() const { return NumArgs; } @@ -2323,7 +2330,7 @@ class TagType : public Type { protected: TagType(TypeClass TC, const TagDecl *D, QualType can); - virtual Linkage getLinkageImpl() const; + virtual std::pair getLinkageUnnamedLocalImpl() const; public: TagDecl *getDecl() const; @@ -2991,7 +2998,7 @@ protected: BaseType(QualType(this_(), 0)) {} protected: - Linkage getLinkageImpl() const; // key function + std::pair getLinkageUnnamedLocalImpl() const; // key function public: /// getBaseType - Gets the base type of this object type. This is @@ -3149,7 +3156,7 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these. protected: - virtual Linkage getLinkageImpl() const; + virtual std::pair getLinkageUnnamedLocalImpl() const; public: /// getPointeeType - Gets the type pointed to by this ObjC pointer. diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 6698e50eba85..5477a4886d7f 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -1276,17 +1276,33 @@ Linkage Type::getLinkage() const { return CanonicalType->getLinkage(); if (!LinkageKnown) { - CachedLinkage = getLinkageImpl(); + std::pair Result = getLinkageUnnamedLocalImpl(); + CachedLinkage = Result.first; + CachedLocalOrUnnamed = Result.second; LinkageKnown = true; } return static_cast(CachedLinkage); } -Linkage Type::getLinkageImpl() const { +bool Type::hasUnnamedOrLocalType() const { + if (this != CanonicalType.getTypePtr()) + return CanonicalType->hasUnnamedOrLocalType(); + + if (!LinkageKnown) { + std::pair Result = getLinkageUnnamedLocalImpl(); + CachedLinkage = Result.first; + CachedLocalOrUnnamed = Result.second; + LinkageKnown = true; + } + + return CachedLocalOrUnnamed; +} + +std::pair Type::getLinkageUnnamedLocalImpl() const { // C++ [basic.link]p8: // Names not covered by these rules have no linkage. - return NoLinkage; + return std::make_pair(NoLinkage, false); } void Type::ClearLinkageCache() { @@ -1296,69 +1312,87 @@ void Type::ClearLinkageCache() { LinkageKnown = false; } -Linkage BuiltinType::getLinkageImpl() const { +std::pair BuiltinType::getLinkageUnnamedLocalImpl() 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 ExternalLinkage; + return std::make_pair(ExternalLinkage, false); } -Linkage TagType::getLinkageImpl() const { +std::pair TagType::getLinkageUnnamedLocalImpl() 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 getDecl()->getLinkage(); + return std::make_pair(getDecl()->getLinkage(), + getDecl()->getDeclContext()->isFunctionOrMethod() || + (!getDecl()->getIdentifier() && + !getDecl()->getTypedefForAnonDecl())); } // 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 -Linkage ComplexType::getLinkageImpl() const { - return ElementType->getLinkage(); +std::pair ComplexType::getLinkageUnnamedLocalImpl() const { + return std::make_pair(ElementType->getLinkage(), + ElementType->hasUnnamedOrLocalType()); } -Linkage PointerType::getLinkageImpl() const { - return PointeeType->getLinkage(); +std::pair PointerType::getLinkageUnnamedLocalImpl() const { + return std::make_pair(PointeeType->getLinkage(), + PointeeType->hasUnnamedOrLocalType()); } -Linkage BlockPointerType::getLinkageImpl() const { - return PointeeType->getLinkage(); +std::pair BlockPointerType::getLinkageUnnamedLocalImpl() const { + return std::make_pair(PointeeType->getLinkage(), + PointeeType->hasUnnamedOrLocalType()); } -Linkage ReferenceType::getLinkageImpl() const { - return PointeeType->getLinkage(); +std::pair ReferenceType::getLinkageUnnamedLocalImpl() const { + return std::make_pair(PointeeType->getLinkage(), + PointeeType->hasUnnamedOrLocalType()); } -Linkage MemberPointerType::getLinkageImpl() const { - return minLinkage(Class->getLinkage(), PointeeType->getLinkage()); +std::pair MemberPointerType::getLinkageUnnamedLocalImpl() const { + return std::make_pair(minLinkage(Class->getLinkage(), + PointeeType->getLinkage()), + Class->hasUnnamedOrLocalType() || + PointeeType->hasUnnamedOrLocalType()); } -Linkage ArrayType::getLinkageImpl() const { - return ElementType->getLinkage(); +std::pair ArrayType::getLinkageUnnamedLocalImpl() const { + return std::make_pair(ElementType->getLinkage(), + ElementType->hasUnnamedOrLocalType()); } -Linkage VectorType::getLinkageImpl() const { - return ElementType->getLinkage(); +std::pair VectorType::getLinkageUnnamedLocalImpl() const { + return std::make_pair(ElementType->getLinkage(), + ElementType->hasUnnamedOrLocalType()); } -Linkage FunctionNoProtoType::getLinkageImpl() const { - return getResultType()->getLinkage(); +std::pair +FunctionNoProtoType::getLinkageUnnamedLocalImpl() const { + return std::make_pair(getResultType()->getLinkage(), + getResultType()->hasUnnamedOrLocalType()); } -Linkage FunctionProtoType::getLinkageImpl() const { +std::pair FunctionProtoType::getLinkageUnnamedLocalImpl() const { Linkage L = getResultType()->getLinkage(); + bool UnnamedOrLocal = getResultType()->hasUnnamedOrLocalType(); for (arg_type_iterator A = arg_type_begin(), AEnd = arg_type_end(); - A != AEnd; ++A) + A != AEnd; ++A) { L = minLinkage(L, (*A)->getLinkage()); - - return L; + UnnamedOrLocal = UnnamedOrLocal || (*A)->hasUnnamedOrLocalType(); + } + + return std::make_pair(L, UnnamedOrLocal); } -Linkage ObjCObjectType::getLinkageImpl() const { - return ExternalLinkage; +std::pair ObjCObjectType::getLinkageUnnamedLocalImpl() const { + return std::make_pair(ExternalLinkage, false); } -Linkage ObjCObjectPointerType::getLinkageImpl() const { - return ExternalLinkage; +std::pair +ObjCObjectPointerType::getLinkageUnnamedLocalImpl() const { + return std::make_pair(ExternalLinkage, false); } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 3b2ca1e162b6..f85c3f00709e 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2582,7 +2582,7 @@ bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param, // // C++0x allows these, and even in C++03 we allow them as an extension with // a warning. - if (!LangOpts.CPlusPlus0x) { + if (!LangOpts.CPlusPlus0x && Arg->hasUnnamedOrLocalType()) { UnnamedLocalNoLinkageFinder Finder(*this, SR); (void)Finder.Visit(Context.getCanonicalType(Arg)); }