aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Decl.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2011-07-17 15:40:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2011-07-17 15:40:56 +0000
commit180abc3db9ae3b4fc63cd65b15697e6ffcc8a657 (patch)
tree2097d084eb235c0b12c0bff3445f4ec7bbaa8a12 /lib/AST/Decl.cpp
parent29cafa66ad3878dbb9f82615f19fa0bded2e443c (diff)
downloadsrc-180abc3db9ae3b4fc63cd65b15697e6ffcc8a657.tar.gz
src-180abc3db9ae3b4fc63cd65b15697e6ffcc8a657.zip
Notes
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r--lib/AST/Decl.cpp110
1 files changed, 83 insertions, 27 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 12357c07a794..4c323da7eee3 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -197,6 +197,16 @@ getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
return getLVForTemplateArgumentList(TArgs.data(), TArgs.size(), F);
}
+static bool shouldConsiderTemplateLV(const FunctionDecl *fn,
+ const FunctionTemplateSpecializationInfo *spec) {
+ return !(spec->isExplicitSpecialization() &&
+ fn->hasAttr<VisibilityAttr>());
+}
+
+static bool shouldConsiderTemplateLV(const ClassTemplateSpecializationDecl *d) {
+ return !(d->isExplicitSpecialization() && d->hasAttr<VisibilityAttr>());
+}
+
static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
assert(D->getDeclContext()->getRedeclContext()->isFileContext() &&
"Not a name having namespace scope");
@@ -231,6 +241,14 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
if (!FoundExtern)
return LinkageInfo::internal();
}
+ if (Var->getStorageClass() == SC_None) {
+ const VarDecl *PrevVar = Var->getPreviousDeclaration();
+ for (; PrevVar; PrevVar = PrevVar->getPreviousDeclaration())
+ if (PrevVar->getStorageClass() == SC_PrivateExtern)
+ break;
+ if (PrevVar)
+ return PrevVar->getLinkageAndVisibility();
+ }
} else if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) {
// C++ [temp]p4:
// A non-member function template can have internal linkage; any
@@ -389,12 +407,16 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
Function->getType()->getLinkage() == UniqueExternalLinkage)
return LinkageInfo::uniqueExternal();
- if (FunctionTemplateSpecializationInfo *SpecInfo
+ // Consider LV from the template and the template arguments unless
+ // this is an explicit specialization with a visibility attribute.
+ if (FunctionTemplateSpecializationInfo *specInfo
= Function->getTemplateSpecializationInfo()) {
- LV.merge(getLVForDecl(SpecInfo->getTemplate(),
- F.onlyTemplateVisibility()));
- const TemplateArgumentList &TemplateArgs = *SpecInfo->TemplateArguments;
- LV.merge(getLVForTemplateArgumentList(TemplateArgs, F));
+ if (shouldConsiderTemplateLV(Function, specInfo)) {
+ LV.merge(getLVForDecl(specInfo->getTemplate(),
+ F.onlyTemplateVisibility()));
+ const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments;
+ LV.merge(getLVForTemplateArgumentList(templateArgs, F));
+ }
}
// - a named class (Clause 9), or an unnamed class defined in a
@@ -410,15 +432,17 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
// If this is a class template specialization, consider the
// linkage of the template and template arguments.
- if (const ClassTemplateSpecializationDecl *Spec
+ if (const ClassTemplateSpecializationDecl *spec
= dyn_cast<ClassTemplateSpecializationDecl>(Tag)) {
- // From the template.
- LV.merge(getLVForDecl(Spec->getSpecializedTemplate(),
- F.onlyTemplateVisibility()));
-
- // The arguments at which the template was instantiated.
- const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- LV.merge(getLVForTemplateArgumentList(TemplateArgs, F));
+ if (shouldConsiderTemplateLV(spec)) {
+ // From the template.
+ LV.merge(getLVForDecl(spec->getSpecializedTemplate(),
+ F.onlyTemplateVisibility()));
+
+ // The arguments at which the template was instantiated.
+ const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs();
+ LV.merge(getLVForTemplateArgumentList(TemplateArgs, F));
+ }
}
// Consider -fvisibility unless the type has C linkage.
@@ -519,14 +543,16 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
// If this is a method template specialization, use the linkage for
// the template parameters and arguments.
- if (FunctionTemplateSpecializationInfo *Spec
+ if (FunctionTemplateSpecializationInfo *spec
= MD->getTemplateSpecializationInfo()) {
- LV.merge(getLVForTemplateArgumentList(*Spec->TemplateArguments, F));
- if (F.ConsiderTemplateParameterTypes)
- LV.merge(getLVForTemplateParameterList(
- Spec->getTemplate()->getTemplateParameters()));
+ if (shouldConsiderTemplateLV(MD, spec)) {
+ LV.merge(getLVForTemplateArgumentList(*spec->TemplateArguments, F));
+ if (F.ConsiderTemplateParameterTypes)
+ LV.merge(getLVForTemplateParameterList(
+ spec->getTemplate()->getTemplateParameters()));
+ }
- TSK = Spec->getTemplateSpecializationKind();
+ TSK = spec->getTemplateSpecializationKind();
} else if (MemberSpecializationInfo *MSI =
MD->getMemberSpecializationInfo()) {
TSK = MSI->getTemplateSpecializationKind();
@@ -553,14 +579,16 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
// *do* apply -fvisibility to method declarations.
} else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
- if (const ClassTemplateSpecializationDecl *Spec
+ if (const ClassTemplateSpecializationDecl *spec
= dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
- // Merge template argument/parameter information for member
- // class template specializations.
- LV.merge(getLVForTemplateArgumentList(Spec->getTemplateArgs(), F));
+ if (shouldConsiderTemplateLV(spec)) {
+ // Merge template argument/parameter information for member
+ // class template specializations.
+ LV.merge(getLVForTemplateArgumentList(spec->getTemplateArgs(), F));
if (F.ConsiderTemplateParameterTypes)
LV.merge(getLVForTemplateParameterList(
- Spec->getSpecializedTemplate()->getTemplateParameters()));
+ spec->getSpecializedTemplate()->getTemplateParameters()));
+ }
}
// Static data members.
@@ -1304,6 +1332,19 @@ void VarDecl::setInit(Expr *I) {
Init = I;
}
+bool VarDecl::extendsLifetimeOfTemporary() const {
+ assert(getType()->isReferenceType() &&"Non-references never extend lifetime");
+
+ const Expr *E = getInit();
+ if (!E)
+ return false;
+
+ if (const ExprWithCleanups *Cleanups = dyn_cast<ExprWithCleanups>(E))
+ E = Cleanups->getSubExpr();
+
+ return isa<MaterializeTemporaryExpr>(E);
+}
+
VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const {
if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
return cast<VarDecl>(MSI->getInstantiatedFrom());
@@ -2320,8 +2361,15 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
ExternalASTSource::Deserializing TheFields(Source);
llvm::SmallVector<Decl*, 64> Decls;
- if (Source->FindExternalLexicalDeclsBy<FieldDecl>(this, Decls))
+ LoadedFieldsFromExternalStorage = true;
+ switch (Source->FindExternalLexicalDeclsBy<FieldDecl>(this, Decls)) {
+ case ELR_Success:
+ break;
+
+ case ELR_AlreadyLoaded:
+ case ELR_Failure:
return;
+ }
#ifndef NDEBUG
// Check that all decls we got were FieldDecls.
@@ -2329,8 +2377,6 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
assert(isa<FieldDecl>(Decls[i]));
#endif
- LoadedFieldsFromExternalStorage = true;
-
if (Decls.empty())
return;
@@ -2376,6 +2422,16 @@ void BlockDecl::setCaptures(ASTContext &Context,
Captures = static_cast<Capture*>(buffer);
}
+bool BlockDecl::capturesVariable(const VarDecl *variable) const {
+ for (capture_const_iterator
+ i = capture_begin(), e = capture_end(); i != e; ++i)
+ // Only auto vars can be captured, so no redeclaration worries.
+ if (i->getVariable() == variable)
+ return true;
+
+ return false;
+}
+
SourceRange BlockDecl::getSourceRange() const {
return SourceRange(getLocation(), Body? Body->getLocEnd() : getLocation());
}