aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Type.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-10-13 18:05:20 +0000
committerDouglas Gregor <dgregor@apple.com>2010-10-13 18:05:20 +0000
commitdb4d4bb03df52920cf379797a7ff5c9900f938a6 (patch)
tree03b7cdd417efc181b83b5a850d9ff33561bee530 /lib/AST/Type.cpp
parentb535041ee33c5eff255832bc5541c8d52aae8254 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116413 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r--lib/AST/Type.cpp96
1 files changed, 65 insertions, 31 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 6698e50eba..5477a4886d 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1276,17 +1276,33 @@ Linkage Type::getLinkage() const {
return CanonicalType->getLinkage();
if (!LinkageKnown) {
- CachedLinkage = getLinkageImpl();
+ std::pair<Linkage, bool> Result = getLinkageUnnamedLocalImpl();
+ CachedLinkage = Result.first;
+ CachedLocalOrUnnamed = Result.second;
LinkageKnown = true;
}
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:
// 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<Linkage, bool> 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<Linkage, bool> 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<Linkage, bool> ComplexType::getLinkageUnnamedLocalImpl() const {
+ return std::make_pair(ElementType->getLinkage(),
+ ElementType->hasUnnamedOrLocalType());
}
-Linkage PointerType::getLinkageImpl() const {
- return PointeeType->getLinkage();
+std::pair<Linkage, bool> PointerType::getLinkageUnnamedLocalImpl() const {
+ return std::make_pair(PointeeType->getLinkage(),
+ PointeeType->hasUnnamedOrLocalType());
}
-Linkage BlockPointerType::getLinkageImpl() const {
- return PointeeType->getLinkage();
+std::pair<Linkage, bool> BlockPointerType::getLinkageUnnamedLocalImpl() const {
+ return std::make_pair(PointeeType->getLinkage(),
+ PointeeType->hasUnnamedOrLocalType());
}
-Linkage ReferenceType::getLinkageImpl() const {
- return PointeeType->getLinkage();
+std::pair<Linkage, bool> ReferenceType::getLinkageUnnamedLocalImpl() const {
+ return std::make_pair(PointeeType->getLinkage(),
+ PointeeType->hasUnnamedOrLocalType());
}
-Linkage MemberPointerType::getLinkageImpl() const {
- return minLinkage(Class->getLinkage(), PointeeType->getLinkage());
+std::pair<Linkage, bool> 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<Linkage, bool> ArrayType::getLinkageUnnamedLocalImpl() const {
+ return std::make_pair(ElementType->getLinkage(),
+ ElementType->hasUnnamedOrLocalType());
}
-Linkage VectorType::getLinkageImpl() const {
- return ElementType->getLinkage();
+std::pair<Linkage, bool> VectorType::getLinkageUnnamedLocalImpl() const {
+ return std::make_pair(ElementType->getLinkage(),
+ ElementType->hasUnnamedOrLocalType());
}
-Linkage FunctionNoProtoType::getLinkageImpl() const {
- return getResultType()->getLinkage();
+std::pair<Linkage, bool>
+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();
+ 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<Linkage, bool> ObjCObjectType::getLinkageUnnamedLocalImpl() const {
+ return std::make_pair(ExternalLinkage, false);
}
-Linkage ObjCObjectPointerType::getLinkageImpl() const {
- return ExternalLinkage;
+std::pair<Linkage, bool>
+ObjCObjectPointerType::getLinkageUnnamedLocalImpl() const {
+ return std::make_pair(ExternalLinkage, false);
}