Update Clang for rebase to r212749.
This also fixes a small issue with arm_neon.h not being generated always.
Includes a cherry-pick of:
r213450 - fixes mac-specific header issue
r213126 - removes a default -Bsymbolic on Android
Change-Id: I2a790a0f5d3b2aab11de596fc3a74e7cbc99081d
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 1c3a538..7448de2 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -471,6 +471,58 @@
LV.mergeExternalVisibility(argsLV);
}
+/// Should we consider visibility associated with the template
+/// arguments and parameters of the given variable template
+/// specialization? As usual, follow class template specialization
+/// logic up to initialization.
+static bool shouldConsiderTemplateVisibility(
+ const VarTemplateSpecializationDecl *spec,
+ LVComputationKind computation) {
+ // Include visibility from the template parameters and arguments
+ // only if this is not an explicit instantiation or specialization
+ // with direct explicit visibility (and note that implicit
+ // instantiations won't have a direct attribute).
+ if (!spec->isExplicitInstantiationOrSpecialization())
+ return true;
+
+ // An explicit variable specialization is an independent, top-level
+ // declaration. As such, if it has an explicit visibility attribute,
+ // that must directly express the user's intent, and we should honor
+ // it.
+ if (spec->isExplicitSpecialization() &&
+ hasExplicitVisibilityAlready(computation))
+ return false;
+
+ return !hasDirectVisibilityAttribute(spec, computation);
+}
+
+/// Merge in template-related linkage and visibility for the given
+/// variable template specialization. As usual, follow class template
+/// specialization logic up to initialization.
+static void mergeTemplateLV(LinkageInfo &LV,
+ const VarTemplateSpecializationDecl *spec,
+ LVComputationKind computation) {
+ bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
+
+ // Merge information from the template parameters, but ignore
+ // visibility if we're only considering template arguments.
+
+ VarTemplateDecl *temp = spec->getSpecializedTemplate();
+ LinkageInfo tempLV =
+ getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
+ LV.mergeMaybeWithVisibility(tempLV,
+ considerVisibility && !hasExplicitVisibilityAlready(computation));
+
+ // Merge information from the template arguments. We ignore
+ // template-argument visibility if we've got an explicit
+ // instantiation with a visibility attribute.
+ const TemplateArgumentList &templateArgs = spec->getTemplateArgs();
+ LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation);
+ if (considerVisibility)
+ LV.mergeVisibility(argsLV);
+ LV.mergeExternalVisibility(argsLV);
+}
+
static bool useInlineVisibilityHidden(const NamedDecl *D) {
// FIXME: we should warn if -fvisibility-inlines-hidden is used with c.
const LangOptions &Opts = D->getASTContext().getLangOpts();
@@ -662,6 +714,14 @@
// C99 6.2.2p4 and propagating the visibility attribute, so we don't have
// to do it here.
+ // As per function and class template specializations (below),
+ // consider LV for the template and template arguments. We're at file
+ // scope, so we do not need to worry about nested specializations.
+ if (const VarTemplateSpecializationDecl *spec
+ = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
+ mergeTemplateLV(LV, spec, computation);
+ }
+
// - a function, unless it has internal linkage; or
} else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
// In theory, we can modify the function's LV by the LV of its
@@ -869,6 +929,10 @@
// Static data members.
} else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const VarTemplateSpecializationDecl *spec
+ = dyn_cast<VarTemplateSpecializationDecl>(VD))
+ mergeTemplateLV(LV, spec, computation);
+
// Modify the variable's linkage by its type, but ignore the
// type's visibility unless it's a definition.
LinkageInfo typeLV = getLVForType(*VD->getType(), computation);
@@ -1303,6 +1367,9 @@
TemplateArgs.size(),
P);
} else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) {
+ if (P.SuppressUnwrittenScope &&
+ (ND->isAnonymousNamespace() || ND->isInline()))
+ continue;
if (ND->isAnonymousNamespace())
OS << "(anonymous namespace)";
else
@@ -1676,7 +1743,7 @@
}
template<typename T>
-static LanguageLinkage getLanguageLinkageTemplate(const T &D) {
+static LanguageLinkage getDeclLanguageLinkage(const T &D) {
// C++ [dcl.link]p1: All function types, function names with external linkage,
// and variable names with external linkage have a language linkage.
if (!D.hasExternalFormalLinkage())
@@ -1704,7 +1771,7 @@
}
template<typename T>
-static bool isExternCTemplate(const T &D) {
+static bool isDeclExternC(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();
@@ -1717,11 +1784,11 @@
}
LanguageLinkage VarDecl::getLanguageLinkage() const {
- return getLanguageLinkageTemplate(*this);
+ return getDeclLanguageLinkage(*this);
}
bool VarDecl::isExternC() const {
- return isExternCTemplate(*this);
+ return isDeclExternC(*this);
}
bool VarDecl::isInExternCContext() const {
@@ -2345,7 +2412,7 @@
return false;
const FunctionProtoType *FPT = getType()->castAs<FunctionProtoType>();
- if (FPT->getNumParams() > 2 || FPT->isVariadic())
+ if (FPT->getNumParams() == 0 || FPT->getNumParams() > 2 || FPT->isVariadic())
return false;
// If this is a single-parameter function, it must be a replaceable global
@@ -2403,11 +2470,11 @@
}
LanguageLinkage FunctionDecl::getLanguageLinkage() const {
- return getLanguageLinkageTemplate(*this);
+ return getDeclLanguageLinkage(*this);
}
bool FunctionDecl::isExternC() const {
- return isExternCTemplate(*this);
+ return isDeclExternC(*this);
}
bool FunctionDecl::isInExternCContext() const {
@@ -2541,6 +2608,18 @@
NamedDecl **A = new (getASTContext()) NamedDecl*[NewDecls.size()];
std::copy(NewDecls.begin(), NewDecls.end(), A);
DeclsInPrototypeScope = ArrayRef<NamedDecl *>(A, NewDecls.size());
+ // Move declarations introduced in prototype to the function context.
+ for (auto I : NewDecls) {
+ DeclContext *DC = I->getDeclContext();
+ // Forward-declared reference to an enumeration is not added to
+ // declaration scope, so skip declaration that is absent from its
+ // declaration contexts.
+ if (DC->containsDecl(I)) {
+ DC->removeDecl(I);
+ I->setDeclContext(this);
+ addDecl(I);
+ }
+ }
}
}
@@ -2672,6 +2751,26 @@
return FoundBody;
}
+SourceRange FunctionDecl::getReturnTypeSourceRange() const {
+ const TypeSourceInfo *TSI = getTypeSourceInfo();
+ if (!TSI)
+ return SourceRange();
+ FunctionTypeLoc FTL =
+ TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>();
+ if (!FTL)
+ return SourceRange();
+
+ // Skip self-referential return types.
+ const SourceManager &SM = getASTContext().getSourceManager();
+ SourceRange RTRange = FTL.getReturnLoc().getSourceRange();
+ SourceLocation Boundary = getNameInfo().getLocStart();
+ if (RTRange.isInvalid() || Boundary.isInvalid() ||
+ !SM.isBeforeInTranslationUnit(RTRange.getEnd(), Boundary))
+ return SourceRange();
+
+ return RTRange;
+}
+
/// \brief For an inline function definition in C, or for a gnu_inline function
/// in C++, determine whether the definition will be externally visible.
///