aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Decl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r--lib/AST/Decl.cpp74
1 files changed, 30 insertions, 44 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index da6f03a34c..4b92069762 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -858,49 +858,14 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
return LV;
}
-static void clearLinkageForClass(const CXXRecordDecl *record) {
- for (CXXRecordDecl::decl_iterator
- i = record->decls_begin(), e = record->decls_end(); i != e; ++i) {
- Decl *child = *i;
- if (isa<NamedDecl>(child))
- cast<NamedDecl>(child)->ClearLinkageCache();
- }
-}
-
void NamedDecl::anchor() { }
-void NamedDecl::ClearLinkageCache() {
- // Note that we can't skip clearing the linkage of children just
- // because the parent doesn't have cached linkage: we don't cache
- // when computing linkage for parent contexts.
-
- HasCachedLinkage = 0;
-
- // If we're changing the linkage of a class, we need to reset the
- // linkage of child declarations, too.
- if (const CXXRecordDecl *record = dyn_cast<CXXRecordDecl>(this))
- clearLinkageForClass(record);
-
- if (ClassTemplateDecl *temp = dyn_cast<ClassTemplateDecl>(this)) {
- // Clear linkage for the template pattern.
- CXXRecordDecl *record = temp->getTemplatedDecl();
- record->HasCachedLinkage = 0;
- clearLinkageForClass(record);
-
- // We need to clear linkage for specializations, too.
- for (ClassTemplateDecl::spec_iterator
- i = temp->spec_begin(), e = temp->spec_end(); i != e; ++i)
- i->ClearLinkageCache();
- }
+bool NamedDecl::isLinkageValid() const {
+ if (!HasCachedLinkage)
+ return true;
- // Clear cached linkage for function template decls, too.
- if (FunctionTemplateDecl *temp = dyn_cast<FunctionTemplateDecl>(this)) {
- temp->getTemplatedDecl()->ClearLinkageCache();
- for (FunctionTemplateDecl::spec_iterator
- i = temp->spec_begin(), e = temp->spec_end(); i != e; ++i)
- i->ClearLinkageCache();
- }
-
+ return getLVForDecl(this, LVForExplicitValue).getLinkage() ==
+ Linkage(CachedLinkage);
}
Linkage NamedDecl::getLinkage() const {
@@ -1515,7 +1480,7 @@ VarDecl *VarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
void VarDecl::setStorageClass(StorageClass SC) {
assert(isLegalForVariable(SC));
if (getStorageClass() != SC)
- ClearLinkageCache();
+ assert(isLinkageValid());
VarDeclBits.SClass = SC;
}
@@ -1560,10 +1525,27 @@ static LanguageLinkage getLanguageLinkageTemplate(const T &D) {
return CXXLanguageLinkage;
}
+template<typename T>
+static bool isExternCTemplate(const T &D) {
+ // Since the context is ignored for class members, they can only have C++
+ // language linkage or no language linkage.
+ const DeclContext *DC = D.getDeclContext();
+ if (DC->isRecord()) {
+ assert(D.getASTContext().getLangOpts().CPlusPlus);
+ return false;
+ }
+
+ return D.getLanguageLinkage() == CLanguageLinkage;
+}
+
LanguageLinkage VarDecl::getLanguageLinkage() const {
return getLanguageLinkageTemplate(*this);
}
+bool VarDecl::isExternC() const {
+ return isExternCTemplate(*this);
+}
+
VarDecl *VarDecl::getCanonicalDecl() {
return getFirstDeclaration();
}
@@ -2077,6 +2059,10 @@ LanguageLinkage FunctionDecl::getLanguageLinkage() const {
return getLanguageLinkageTemplate(*this);
}
+bool FunctionDecl::isExternC() const {
+ return isExternCTemplate(*this);
+}
+
bool FunctionDecl::isGlobal() const {
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this))
return Method->isStatic();
@@ -2129,7 +2115,7 @@ FunctionDecl *FunctionDecl::getCanonicalDecl() {
void FunctionDecl::setStorageClass(StorageClass SC) {
assert(isLegalForFunction(SC));
if (getStorageClass() != SC)
- ClearLinkageCache();
+ assert(isLinkageValid());
SClass = SC;
}
@@ -2867,8 +2853,8 @@ TagDecl* TagDecl::getCanonicalDecl() {
void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) {
TypedefNameDeclOrQualifier = TDD;
if (TypeForDecl)
- const_cast<Type*>(TypeForDecl)->ClearLinkageCache();
- ClearLinkageCache();
+ assert(TypeForDecl->isLinkageValid());
+ assert(isLinkageValid());
}
void TagDecl::startDefinition() {