Introduce a bit into Type that keeps track of whether there are any
unnamed or local types within that type. This bit is cached along with the linkage of a type, so that it can be recomputed (e.g., when we see that a typedef has given a name to an anonymous declaration). Use this bit when checking C++03 [temp.arg.type]p2, so that we don't walk template argument types repeatedly. llvm-svn: 116413
This commit is contained in:
parent
651dc7c9e9
commit
52051cb173
|
@ -796,12 +796,16 @@ private:
|
||||||
/// \brief Whether this type is a variably-modified type (C99 6.7.5).
|
/// \brief Whether this type is a variably-modified type (C99 6.7.5).
|
||||||
bool VariablyModified : 1;
|
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;
|
mutable bool LinkageKnown : 1;
|
||||||
|
|
||||||
/// \brief Linkage of this type.
|
/// \brief Linkage of this type.
|
||||||
mutable unsigned CachedLinkage : 2;
|
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.
|
/// \brief FromAST - Whether this type comes from an AST file.
|
||||||
mutable bool FromAST : 1;
|
mutable bool FromAST : 1;
|
||||||
|
|
||||||
|
@ -813,7 +817,7 @@ private:
|
||||||
protected:
|
protected:
|
||||||
/// \brief Compute the linkage of this type along with the presence of
|
/// \brief Compute the linkage of this type along with the presence of
|
||||||
/// any local or unnamed types.
|
/// any local or unnamed types.
|
||||||
virtual Linkage getLinkageImpl() const;
|
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||||
|
|
||||||
enum { BitsRemainingInType = 19 };
|
enum { BitsRemainingInType = 19 };
|
||||||
|
|
||||||
|
@ -959,6 +963,9 @@ public:
|
||||||
/// \brief Whether this type is a variably-modified type (C99 6.7.5).
|
/// \brief Whether this type is a variably-modified type (C99 6.7.5).
|
||||||
bool isVariablyModifiedType() const { return VariablyModified; }
|
bool isVariablyModifiedType() const { return VariablyModified; }
|
||||||
|
|
||||||
|
/// \brief Whether this type is or contains a local or unnamed type.
|
||||||
|
bool hasUnnamedOrLocalType() const;
|
||||||
|
|
||||||
bool isOverloadableType() const;
|
bool isOverloadableType() const;
|
||||||
|
|
||||||
/// \brief Determine wither this type is a C++ elaborated-type-specifier.
|
/// \brief Determine wither this type is a C++ elaborated-type-specifier.
|
||||||
|
@ -1146,7 +1153,7 @@ private:
|
||||||
Kind TypeKind;
|
Kind TypeKind;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Linkage getLinkageImpl() const;
|
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BuiltinType(Kind K)
|
BuiltinType(Kind K)
|
||||||
|
@ -1201,7 +1208,7 @@ class ComplexType : public Type, public llvm::FoldingSetNode {
|
||||||
friend class ASTContext; // ASTContext creates these.
|
friend class ASTContext; // ASTContext creates these.
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Linkage getLinkageImpl() const;
|
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QualType getElementType() const { return ElementType; }
|
QualType getElementType() const { return ElementType; }
|
||||||
|
@ -1233,7 +1240,7 @@ class PointerType : public Type, public llvm::FoldingSetNode {
|
||||||
friend class ASTContext; // ASTContext creates these.
|
friend class ASTContext; // ASTContext creates these.
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Linkage getLinkageImpl() const;
|
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -1267,7 +1274,7 @@ class BlockPointerType : public Type, public llvm::FoldingSetNode {
|
||||||
friend class ASTContext; // ASTContext creates these.
|
friend class ASTContext; // ASTContext creates these.
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Linkage getLinkageImpl() const;
|
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -1321,7 +1328,7 @@ protected:
|
||||||
InnerRef(Referencee->isReferenceType()) {
|
InnerRef(Referencee->isReferenceType()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Linkage getLinkageImpl() const;
|
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool isSpelledAsLValue() const { return SpelledAsLValue; }
|
bool isSpelledAsLValue() const { return SpelledAsLValue; }
|
||||||
|
@ -1405,7 +1412,7 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
|
||||||
friend class ASTContext; // ASTContext creates these.
|
friend class ASTContext; // ASTContext creates these.
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Linkage getLinkageImpl() const;
|
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QualType getPointeeType() const { return PointeeType; }
|
QualType getPointeeType() const { return PointeeType; }
|
||||||
|
@ -1479,7 +1486,7 @@ protected:
|
||||||
|
|
||||||
friend class ASTContext; // ASTContext creates these.
|
friend class ASTContext; // ASTContext creates these.
|
||||||
|
|
||||||
virtual Linkage getLinkageImpl() const;
|
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QualType getElementType() const { return ElementType; }
|
QualType getElementType() const { return ElementType; }
|
||||||
|
@ -1782,7 +1789,7 @@ protected:
|
||||||
NumElements(nElements), AltiVecSpec(altiVecSpec) {}
|
NumElements(nElements), AltiVecSpec(altiVecSpec) {}
|
||||||
friend class ASTContext; // ASTContext creates these.
|
friend class ASTContext; // ASTContext creates these.
|
||||||
|
|
||||||
virtual Linkage getLinkageImpl() const;
|
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -2023,7 +2030,7 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
|
||||||
friend class ASTContext; // ASTContext creates these.
|
friend class ASTContext; // ASTContext creates these.
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Linkage getLinkageImpl() const;
|
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// No additional state past what FunctionType provides.
|
// No additional state past what FunctionType provides.
|
||||||
|
@ -2081,7 +2088,7 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
|
||||||
friend class ASTContext; // ASTContext creates these.
|
friend class ASTContext; // ASTContext creates these.
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Linkage getLinkageImpl() const;
|
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned getNumArgs() const { return NumArgs; }
|
unsigned getNumArgs() const { return NumArgs; }
|
||||||
|
@ -2323,7 +2330,7 @@ class TagType : public Type {
|
||||||
protected:
|
protected:
|
||||||
TagType(TypeClass TC, const TagDecl *D, QualType can);
|
TagType(TypeClass TC, const TagDecl *D, QualType can);
|
||||||
|
|
||||||
virtual Linkage getLinkageImpl() const;
|
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TagDecl *getDecl() const;
|
TagDecl *getDecl() const;
|
||||||
|
@ -2991,7 +2998,7 @@ protected:
|
||||||
BaseType(QualType(this_(), 0)) {}
|
BaseType(QualType(this_(), 0)) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Linkage getLinkageImpl() const; // key function
|
std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const; // key function
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// getBaseType - Gets the base type of this object type. This is
|
/// 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.
|
friend class ASTContext; // ASTContext creates these.
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Linkage getLinkageImpl() const;
|
virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// getPointeeType - Gets the type pointed to by this ObjC pointer.
|
/// getPointeeType - Gets the type pointed to by this ObjC pointer.
|
||||||
|
|
|
@ -1276,17 +1276,33 @@ Linkage Type::getLinkage() const {
|
||||||
return CanonicalType->getLinkage();
|
return CanonicalType->getLinkage();
|
||||||
|
|
||||||
if (!LinkageKnown) {
|
if (!LinkageKnown) {
|
||||||
CachedLinkage = getLinkageImpl();
|
std::pair<Linkage, bool> Result = getLinkageUnnamedLocalImpl();
|
||||||
|
CachedLinkage = Result.first;
|
||||||
|
CachedLocalOrUnnamed = Result.second;
|
||||||
LinkageKnown = true;
|
LinkageKnown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_cast<clang::Linkage>(CachedLinkage);
|
return static_cast<clang::Linkage>(CachedLinkage);
|
||||||
}
|
}
|
||||||
|
|
||||||
Linkage Type::getLinkageImpl() const {
|
bool Type::hasUnnamedOrLocalType() const {
|
||||||
|
if (this != CanonicalType.getTypePtr())
|
||||||
|
return CanonicalType->hasUnnamedOrLocalType();
|
||||||
|
|
||||||
|
if (!LinkageKnown) {
|
||||||
|
std::pair<Linkage, bool> Result = getLinkageUnnamedLocalImpl();
|
||||||
|
CachedLinkage = Result.first;
|
||||||
|
CachedLocalOrUnnamed = Result.second;
|
||||||
|
LinkageKnown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CachedLocalOrUnnamed;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<Linkage, bool> Type::getLinkageUnnamedLocalImpl() const {
|
||||||
// C++ [basic.link]p8:
|
// C++ [basic.link]p8:
|
||||||
// Names not covered by these rules have no linkage.
|
// Names not covered by these rules have no linkage.
|
||||||
return NoLinkage;
|
return std::make_pair(NoLinkage, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Type::ClearLinkageCache() {
|
void Type::ClearLinkageCache() {
|
||||||
|
@ -1296,69 +1312,87 @@ void Type::ClearLinkageCache() {
|
||||||
LinkageKnown = false;
|
LinkageKnown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Linkage BuiltinType::getLinkageImpl() const {
|
std::pair<Linkage, bool> BuiltinType::getLinkageUnnamedLocalImpl() const {
|
||||||
// C++ [basic.link]p8:
|
// C++ [basic.link]p8:
|
||||||
// A type is said to have linkage if and only if:
|
// A type is said to have linkage if and only if:
|
||||||
// - it is a fundamental type (3.9.1); or
|
// - it is a fundamental type (3.9.1); or
|
||||||
return ExternalLinkage;
|
return std::make_pair(ExternalLinkage, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Linkage TagType::getLinkageImpl() const {
|
std::pair<Linkage, bool> TagType::getLinkageUnnamedLocalImpl() const {
|
||||||
// C++ [basic.link]p8:
|
// C++ [basic.link]p8:
|
||||||
// - it is a class or enumeration type that is named (or has a name for
|
// - 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
|
// linkage purposes (7.1.3)) and the name has linkage; or
|
||||||
// - it is a specialization of a class template (14); 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:
|
// C++ [basic.link]p8:
|
||||||
// - it is a compound type (3.9.2) other than a class or enumeration,
|
// - it is a compound type (3.9.2) other than a class or enumeration,
|
||||||
// compounded exclusively from types that have linkage; or
|
// compounded exclusively from types that have linkage; or
|
||||||
Linkage ComplexType::getLinkageImpl() const {
|
std::pair<Linkage, bool> ComplexType::getLinkageUnnamedLocalImpl() const {
|
||||||
return ElementType->getLinkage();
|
return std::make_pair(ElementType->getLinkage(),
|
||||||
|
ElementType->hasUnnamedOrLocalType());
|
||||||
}
|
}
|
||||||
|
|
||||||
Linkage PointerType::getLinkageImpl() const {
|
std::pair<Linkage, bool> PointerType::getLinkageUnnamedLocalImpl() const {
|
||||||
return PointeeType->getLinkage();
|
return std::make_pair(PointeeType->getLinkage(),
|
||||||
|
PointeeType->hasUnnamedOrLocalType());
|
||||||
}
|
}
|
||||||
|
|
||||||
Linkage BlockPointerType::getLinkageImpl() const {
|
std::pair<Linkage, bool> BlockPointerType::getLinkageUnnamedLocalImpl() const {
|
||||||
return PointeeType->getLinkage();
|
return std::make_pair(PointeeType->getLinkage(),
|
||||||
|
PointeeType->hasUnnamedOrLocalType());
|
||||||
}
|
}
|
||||||
|
|
||||||
Linkage ReferenceType::getLinkageImpl() const {
|
std::pair<Linkage, bool> ReferenceType::getLinkageUnnamedLocalImpl() const {
|
||||||
return PointeeType->getLinkage();
|
return std::make_pair(PointeeType->getLinkage(),
|
||||||
|
PointeeType->hasUnnamedOrLocalType());
|
||||||
}
|
}
|
||||||
|
|
||||||
Linkage MemberPointerType::getLinkageImpl() const {
|
std::pair<Linkage, bool> MemberPointerType::getLinkageUnnamedLocalImpl() const {
|
||||||
return minLinkage(Class->getLinkage(), PointeeType->getLinkage());
|
return std::make_pair(minLinkage(Class->getLinkage(),
|
||||||
|
PointeeType->getLinkage()),
|
||||||
|
Class->hasUnnamedOrLocalType() ||
|
||||||
|
PointeeType->hasUnnamedOrLocalType());
|
||||||
}
|
}
|
||||||
|
|
||||||
Linkage ArrayType::getLinkageImpl() const {
|
std::pair<Linkage, bool> ArrayType::getLinkageUnnamedLocalImpl() const {
|
||||||
return ElementType->getLinkage();
|
return std::make_pair(ElementType->getLinkage(),
|
||||||
|
ElementType->hasUnnamedOrLocalType());
|
||||||
}
|
}
|
||||||
|
|
||||||
Linkage VectorType::getLinkageImpl() const {
|
std::pair<Linkage, bool> VectorType::getLinkageUnnamedLocalImpl() const {
|
||||||
return ElementType->getLinkage();
|
return std::make_pair(ElementType->getLinkage(),
|
||||||
|
ElementType->hasUnnamedOrLocalType());
|
||||||
}
|
}
|
||||||
|
|
||||||
Linkage FunctionNoProtoType::getLinkageImpl() const {
|
std::pair<Linkage, bool>
|
||||||
return getResultType()->getLinkage();
|
FunctionNoProtoType::getLinkageUnnamedLocalImpl() const {
|
||||||
|
return std::make_pair(getResultType()->getLinkage(),
|
||||||
|
getResultType()->hasUnnamedOrLocalType());
|
||||||
}
|
}
|
||||||
|
|
||||||
Linkage FunctionProtoType::getLinkageImpl() const {
|
std::pair<Linkage, bool> FunctionProtoType::getLinkageUnnamedLocalImpl() const {
|
||||||
Linkage L = getResultType()->getLinkage();
|
Linkage L = getResultType()->getLinkage();
|
||||||
|
bool UnnamedOrLocal = getResultType()->hasUnnamedOrLocalType();
|
||||||
for (arg_type_iterator A = arg_type_begin(), AEnd = arg_type_end();
|
for (arg_type_iterator A = arg_type_begin(), AEnd = arg_type_end();
|
||||||
A != AEnd; ++A)
|
A != AEnd; ++A) {
|
||||||
L = minLinkage(L, (*A)->getLinkage());
|
L = minLinkage(L, (*A)->getLinkage());
|
||||||
|
UnnamedOrLocal = UnnamedOrLocal || (*A)->hasUnnamedOrLocalType();
|
||||||
|
}
|
||||||
|
|
||||||
return L;
|
return std::make_pair(L, UnnamedOrLocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
Linkage ObjCObjectType::getLinkageImpl() const {
|
std::pair<Linkage, bool> ObjCObjectType::getLinkageUnnamedLocalImpl() const {
|
||||||
return ExternalLinkage;
|
return std::make_pair(ExternalLinkage, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Linkage ObjCObjectPointerType::getLinkageImpl() const {
|
std::pair<Linkage, bool>
|
||||||
return ExternalLinkage;
|
ObjCObjectPointerType::getLinkageUnnamedLocalImpl() const {
|
||||||
|
return std::make_pair(ExternalLinkage, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
// C++0x allows these, and even in C++03 we allow them as an extension with
|
||||||
// a warning.
|
// a warning.
|
||||||
if (!LangOpts.CPlusPlus0x) {
|
if (!LangOpts.CPlusPlus0x && Arg->hasUnnamedOrLocalType()) {
|
||||||
UnnamedLocalNoLinkageFinder Finder(*this, SR);
|
UnnamedLocalNoLinkageFinder Finder(*this, SR);
|
||||||
(void)Finder.Visit(Context.getCanonicalType(Arg));
|
(void)Finder.Visit(Context.getCanonicalType(Arg));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue