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.cpp634
1 files changed, 328 insertions, 306 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 573a98efe980..2f51ec31a7bd 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1,4 +1,4 @@
-//===--- Decl.cpp - Declaration AST Node Implementation -------------------===//
+//===- Decl.cpp - Declaration AST Node Implementation ---------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,27 +12,62 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/Decl.h"
+#include "Linkage.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/ASTMutationListener.h"
-#include "clang/AST/Attr.h"
+#include "clang/AST/CanonicalType.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/Redeclarable.h"
#include "clang/AST/Stmt.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Linkage.h"
#include "clang/Basic/Module.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SanitizerBlacklist.h"
+#include "clang/Basic/Sanitizers.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TargetCXXABI.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Visibility.h"
#include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <type_traits>
using namespace clang;
@@ -47,7 +82,7 @@ bool Decl::isOutOfLine() const {
TranslationUnitDecl::TranslationUnitDecl(ASTContext &ctx)
: Decl(TranslationUnit, nullptr, SourceLocation()),
- DeclContext(TranslationUnit), Ctx(ctx), AnonymousNamespace(nullptr) {}
+ DeclContext(TranslationUnit), Ctx(ctx) {}
//===----------------------------------------------------------------------===//
// NamedDecl Implementation
@@ -99,63 +134,25 @@ TranslationUnitDecl::TranslationUnitDecl(ASTContext &ctx)
// and 'matcher' is a type only matters when looking for attributes
// and settings from the immediate context.
-const unsigned IgnoreExplicitVisibilityBit = 2;
-const unsigned IgnoreAllVisibilityBit = 4;
-
-/// Kinds of LV computation. The linkage side of the computation is
-/// always the same, but different things can change how visibility is
-/// computed.
-enum LVComputationKind {
- /// Do an LV computation for, ultimately, a type.
- /// Visibility may be restricted by type visibility settings and
- /// the visibility of template arguments.
- LVForType = NamedDecl::VisibilityForType,
-
- /// Do an LV computation for, ultimately, a non-type declaration.
- /// Visibility may be restricted by value visibility settings and
- /// the visibility of template arguments.
- LVForValue = NamedDecl::VisibilityForValue,
-
- /// Do an LV computation for, ultimately, a type that already has
- /// some sort of explicit visibility. Visibility may only be
- /// restricted by the visibility of template arguments.
- LVForExplicitType = (LVForType | IgnoreExplicitVisibilityBit),
-
- /// Do an LV computation for, ultimately, a non-type declaration
- /// that already has some sort of explicit visibility. Visibility
- /// may only be restricted by the visibility of template arguments.
- LVForExplicitValue = (LVForValue | IgnoreExplicitVisibilityBit),
-
- /// Do an LV computation when we only care about the linkage.
- LVForLinkageOnly =
- LVForValue | IgnoreExplicitVisibilityBit | IgnoreAllVisibilityBit
-};
-
/// Does this computation kind permit us to consider additional
/// visibility settings from attributes and the like?
static bool hasExplicitVisibilityAlready(LVComputationKind computation) {
- return ((unsigned(computation) & IgnoreExplicitVisibilityBit) != 0);
+ return computation.IgnoreExplicitVisibility;
}
/// Given an LVComputationKind, return one of the same type/value sort
/// that records that it already has explicit visibility.
static LVComputationKind
-withExplicitVisibilityAlready(LVComputationKind oldKind) {
- LVComputationKind newKind =
- static_cast<LVComputationKind>(unsigned(oldKind) |
- IgnoreExplicitVisibilityBit);
- assert(oldKind != LVForType || newKind == LVForExplicitType);
- assert(oldKind != LVForValue || newKind == LVForExplicitValue);
- assert(oldKind != LVForExplicitType || newKind == LVForExplicitType);
- assert(oldKind != LVForExplicitValue || newKind == LVForExplicitValue);
- return newKind;
+withExplicitVisibilityAlready(LVComputationKind Kind) {
+ Kind.IgnoreExplicitVisibility = true;
+ return Kind;
}
static Optional<Visibility> getExplicitVisibility(const NamedDecl *D,
LVComputationKind kind) {
- assert(!hasExplicitVisibilityAlready(kind) &&
+ assert(!kind.IgnoreExplicitVisibility &&
"asking for explicit visibility when we shouldn't be");
- return D->getExplicitVisibility((NamedDecl::ExplicitVisibilityKind) kind);
+ return D->getExplicitVisibility(kind.getExplicitVisibilityKind());
}
/// Is the given declaration a "type" or a "value" for the purposes of
@@ -216,30 +213,21 @@ static Optional<Visibility> getVisibilityOf(const NamedDecl *D,
return getVisibilityFromAttr(A);
}
- // If we're on Mac OS X, an 'availability' for Mac OS X attribute
- // implies visibility(default).
- if (D->getASTContext().getTargetInfo().getTriple().isOSDarwin()) {
- for (const auto *A : D->specific_attrs<AvailabilityAttr>())
- if (A->getPlatform()->getName().equals("macos"))
- return DefaultVisibility;
- }
-
return None;
}
-static LinkageInfo
-getLVForType(const Type &T, LVComputationKind computation) {
- if (computation == LVForLinkageOnly)
+LinkageInfo LinkageComputer::getLVForType(const Type &T,
+ LVComputationKind computation) {
+ if (computation.IgnoreAllVisibility)
return LinkageInfo(T.getLinkage(), DefaultVisibility, true);
- return T.getLinkageAndVisibility();
+ return getTypeLinkageAndVisibility(&T);
}
/// \brief Get the most restrictive linkage for the types in the given
/// template parameter list. For visibility purposes, template
/// parameters are part of the signature of a template.
-static LinkageInfo
-getLVForTemplateParameterList(const TemplateParameterList *Params,
- LVComputationKind computation) {
+LinkageInfo LinkageComputer::getLVForTemplateParameterList(
+ const TemplateParameterList *Params, LVComputationKind computation) {
LinkageInfo LV;
for (const NamedDecl *P : *Params) {
// Template type parameters are the most common and never
@@ -264,7 +252,7 @@ getLVForTemplateParameterList(const TemplateParameterList *Params,
for (unsigned i = 0, n = NTTP->getNumExpansionTypes(); i != n; ++i) {
QualType type = NTTP->getExpansionType(i);
if (!type->isDependentType())
- LV.merge(type->getLinkageAndVisibility());
+ LV.merge(getTypeLinkageAndVisibility(type));
}
continue;
}
@@ -291,10 +279,6 @@ getLVForTemplateParameterList(const TemplateParameterList *Params,
return LV;
}
-/// getLVForDecl - Get the linkage and visibility for the given declaration.
-static LinkageInfo getLVForDecl(const NamedDecl *D,
- LVComputationKind computation);
-
static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {
const Decl *Ret = nullptr;
const DeclContext *DC = D->getDeclContext();
@@ -311,8 +295,9 @@ static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {
///
/// Note that we don't take an LVComputationKind because we always
/// want to honor the visibility of template arguments in the same way.
-static LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
- LVComputationKind computation) {
+LinkageInfo
+LinkageComputer::getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
+ LVComputationKind computation) {
LinkageInfo LV;
for (const TemplateArgument &Arg : Args) {
@@ -334,7 +319,7 @@ static LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
continue;
case TemplateArgument::NullPtr:
- LV.merge(Arg.getNullPtrType()->getLinkageAndVisibility());
+ LV.merge(getTypeLinkageAndVisibility(Arg.getNullPtrType()));
continue;
case TemplateArgument::Template:
@@ -354,9 +339,9 @@ static LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
return LV;
}
-static LinkageInfo
-getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
- LVComputationKind computation) {
+LinkageInfo
+LinkageComputer::getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
+ LVComputationKind computation) {
return getLVForTemplateArgumentList(TArgs.asArray(), computation);
}
@@ -379,10 +364,10 @@ static bool shouldConsiderTemplateVisibility(const FunctionDecl *fn,
/// LVForValue.
///
/// \param[out] LV the computation to use for the parent
-static void
-mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
- const FunctionTemplateSpecializationInfo *specInfo,
- LVComputationKind computation) {
+void LinkageComputer::mergeTemplateLV(
+ LinkageInfo &LV, const FunctionDecl *fn,
+ const FunctionTemplateSpecializationInfo *specInfo,
+ LVComputationKind computation) {
bool considerVisibility =
shouldConsiderTemplateVisibility(fn, specInfo);
@@ -402,21 +387,11 @@ mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
/// that would match the given rules?
static bool hasDirectVisibilityAttribute(const NamedDecl *D,
LVComputationKind computation) {
- switch (computation) {
- case LVForType:
- case LVForExplicitType:
- if (D->hasAttr<TypeVisibilityAttr>())
- return true;
- // fallthrough
- case LVForValue:
- case LVForExplicitValue:
- if (D->hasAttr<VisibilityAttr>())
- return true;
+ if (computation.IgnoreAllVisibility)
return false;
- case LVForLinkageOnly:
- return false;
- }
- llvm_unreachable("bad visibility computation kind");
+
+ return (computation.isTypeVisibility() && D->hasAttr<TypeVisibilityAttr>()) ||
+ D->hasAttr<VisibilityAttr>();
}
/// Should we consider visibility associated with the template
@@ -457,9 +432,9 @@ static bool shouldConsiderTemplateVisibility(
/// Merge in template-related linkage and visibility for the given
/// class template specialization.
-static void mergeTemplateLV(LinkageInfo &LV,
- const ClassTemplateSpecializationDecl *spec,
- LVComputationKind computation) {
+void LinkageComputer::mergeTemplateLV(
+ LinkageInfo &LV, const ClassTemplateSpecializationDecl *spec,
+ LVComputationKind computation) {
bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
// Merge information from the template parameters, but ignore
@@ -509,9 +484,9 @@ static bool shouldConsiderTemplateVisibility(
/// 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) {
+void LinkageComputer::mergeTemplateLV(LinkageInfo &LV,
+ const VarTemplateSpecializationDecl *spec,
+ LVComputationKind computation) {
bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
// Merge information from the template parameters, but ignore
@@ -574,6 +549,7 @@ static bool isSingleLineLanguageLinkage(const Decl &D) {
}
static bool isExportedFromModuleIntefaceUnit(const NamedDecl *D) {
+ // FIXME: Handle isModulePrivate.
switch (D->getModuleOwnershipKind()) {
case Decl::ModuleOwnershipKind::Unowned:
case Decl::ModuleOwnershipKind::ModulePrivate:
@@ -605,14 +581,17 @@ static LinkageInfo getExternalLinkageFor(const NamedDecl *D) {
// declaration has module linkage.
if (auto *M = D->getOwningModule())
if (M->Kind == Module::ModuleInterfaceUnit)
- if (!isExportedFromModuleIntefaceUnit(D))
+ if (!isExportedFromModuleIntefaceUnit(
+ cast<NamedDecl>(D->getCanonicalDecl())))
return LinkageInfo(ModuleLinkage, DefaultVisibility, false);
return LinkageInfo::external();
}
-static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
- LVComputationKind computation) {
+LinkageInfo
+LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
+ LVComputationKind computation,
+ bool IgnoreVarTypeLinkage) {
assert(D->getDeclContext()->getRedeclContext()->isFileContext() &&
"Not a name having namespace scope");
ASTContext &Context = D->getASTContext();
@@ -652,7 +631,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
PrevVar = PrevVar->getPreviousDecl()) {
if (PrevVar->getStorageClass() == SC_PrivateExtern &&
Var->getStorageClass() == SC_None)
- return PrevVar->getLinkageAndVisibility();
+ return getDeclLinkageAndVisibility(PrevVar);
// Explicitly declared static.
if (PrevVar->getStorageClass() == SC_Static)
return getInternalLinkageFor(Var);
@@ -669,23 +648,23 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// - a data member of an anonymous union.
const VarDecl *VD = IFD->getVarDecl();
assert(VD && "Expected a VarDecl in this IndirectFieldDecl!");
- return getLVForNamespaceScopeDecl(VD, computation);
+ return getLVForNamespaceScopeDecl(VD, computation, IgnoreVarTypeLinkage);
}
assert(!isa<FieldDecl>(D) && "Didn't expect a FieldDecl!");
if (D->isInAnonymousNamespace()) {
const auto *Var = dyn_cast<VarDecl>(D);
const auto *Func = dyn_cast<FunctionDecl>(D);
- // FIXME: In C++11 onwards, anonymous namespaces should give decls
- // within them (including those inside extern "C" contexts) internal
- // linkage, not unique external linkage:
+ // FIXME: The check for extern "C" here is not justified by the standard
+ // wording, but we retain it from the pre-DR1113 model to avoid breaking
+ // code.
//
// C++11 [basic.link]p4:
// An unnamed namespace or a namespace declared directly or indirectly
// within an unnamed namespace has internal linkage.
if ((!Var || !isFirstInExternCContext(Var)) &&
(!Func || !isFirstInExternCContext(Func)))
- return LinkageInfo::uniqueExternal();
+ return getInternalLinkageFor(D);
}
// Set up the defaults.
@@ -694,7 +673,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// If the declaration of an identifier for an object has file
// scope and no storage-class specifier, its linkage is
// external.
- LinkageInfo LV;
+ LinkageInfo LV = getExternalLinkageFor(D);
if (!hasExplicitVisibilityAlready(computation)) {
if (Optional<Visibility> Vis = getExplicitVisibility(D, computation)) {
@@ -717,13 +696,10 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// Add in global settings if the above didn't give us direct visibility.
if (!LV.isVisibilityExplicit()) {
// Use global type/value visibility as appropriate.
- Visibility globalVisibility;
- if (computation == LVForValue) {
- globalVisibility = Context.getLangOpts().getValueVisibilityMode();
- } else {
- assert(computation == LVForType);
- globalVisibility = Context.getLangOpts().getTypeVisibilityMode();
- }
+ Visibility globalVisibility =
+ computation.isValueVisibility()
+ ? Context.getLangOpts().getValueVisibilityMode()
+ : Context.getLangOpts().getTypeVisibilityMode();
LV.mergeVisibility(globalVisibility, /*explicit*/ false);
// If we're paying attention to global visibility, apply
@@ -761,10 +737,10 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
//
// Note that we don't want to make the variable non-external
// because of this, but unique-external linkage suits us.
- if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Var)) {
+ if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Var) &&
+ !IgnoreVarTypeLinkage) {
LinkageInfo TypeLV = getLVForType(*Var->getType(), computation);
- if (TypeLV.getLinkage() != ExternalLinkage &&
- TypeLV.getLinkage() != ModuleLinkage)
+ if (!isExternallyVisible(TypeLV.getLinkage()))
return LinkageInfo::uniqueExternal();
if (!LV.isVisibilityExplicit())
LV.mergeVisibility(TypeLV);
@@ -802,19 +778,13 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// unique-external linkage, it's not legally usable from outside
// this translation unit. However, we should use the C linkage
// rules instead for extern "C" declarations.
- if (Context.getLangOpts().CPlusPlus &&
- !Function->isInExternCContext()) {
- // Only look at the type-as-written. If this function has an auto-deduced
- // return type, we can't compute the linkage of that type because it could
- // require looking at the linkage of this function, and we don't need this
- // for correctness because the type is not part of the function's
- // signature.
- // FIXME: This is a hack. We should be able to solve this circularity and
- // the one in getLVForClassMember for Functions some other way.
+ if (Context.getLangOpts().CPlusPlus && !Function->isInExternCContext()) {
+ // Only look at the type-as-written. Otherwise, deducing the return type
+ // of a function could change its linkage.
QualType TypeAsWritten = Function->getType();
if (TypeSourceInfo *TSI = Function->getTypeSourceInfo())
TypeAsWritten = TSI->getType();
- if (TypeAsWritten->getLinkage() == UniqueExternalLinkage)
+ if (!isExternallyVisible(TypeAsWritten->getLinkage()))
return LinkageInfo::uniqueExternal();
}
@@ -883,16 +853,18 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
return LinkageInfo::none();
}
- // If we ended up with non-external linkage, visibility should
+ // If we ended up with non-externally-visible linkage, visibility should
// always be default.
- if (LV.getLinkage() != ExternalLinkage)
+ if (!isExternallyVisible(LV.getLinkage()))
return LinkageInfo(LV.getLinkage(), DefaultVisibility, false);
return LV;
}
-static LinkageInfo getLVForClassMember(const NamedDecl *D,
- LVComputationKind computation) {
+LinkageInfo
+LinkageComputer::getLVForClassMember(const NamedDecl *D,
+ LVComputationKind computation,
+ bool IgnoreVarTypeLinkage) {
// Only certain class members have linkage. Note that fields don't
// really have linkage, but it's convenient to say they do for the
// purposes of calculating linkage of pointer-to-data-member
@@ -935,12 +907,11 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
LinkageInfo classLV =
getLVForDecl(cast<RecordDecl>(D->getDeclContext()), classComputation);
- // If the class already has unique-external linkage, we can't improve.
- if (classLV.getLinkage() == UniqueExternalLinkage)
- return LinkageInfo::uniqueExternal();
-
+ // The member has the same linkage as the class. If that's not externally
+ // visible, we don't need to compute anything about the linkage.
+ // FIXME: If we're only computing linkage, can we bail out here?
if (!isExternallyVisible(classLV.getLinkage()))
- return LinkageInfo::none();
+ return classLV;
// Otherwise, don't merge in classLV yet, because in certain cases
@@ -950,22 +921,14 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
const NamedDecl *explicitSpecSuppressor = nullptr;
if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
- // If the type of the function uses a type with unique-external
- // linkage, it's not legally usable from outside this translation unit.
- // But only look at the type-as-written. If this function has an
- // auto-deduced return type, we can't compute the linkage of that type
- // because it could require looking at the linkage of this function, and we
- // don't need this for correctness because the type is not part of the
- // function's signature.
- // FIXME: This is a hack. We should be able to solve this circularity and
- // the one in getLVForNamespaceScopeDecl for Functions some other way.
- {
- QualType TypeAsWritten = MD->getType();
- if (TypeSourceInfo *TSI = MD->getTypeSourceInfo())
- TypeAsWritten = TSI->getType();
- if (TypeAsWritten->getLinkage() == UniqueExternalLinkage)
- return LinkageInfo::uniqueExternal();
- }
+ // Only look at the type-as-written. Otherwise, deducing the return type
+ // of a function could change its linkage.
+ QualType TypeAsWritten = MD->getType();
+ if (TypeSourceInfo *TSI = MD->getTypeSourceInfo())
+ TypeAsWritten = TSI->getType();
+ if (!isExternallyVisible(TypeAsWritten->getLinkage()))
+ return LinkageInfo::uniqueExternal();
+
// If this is a method template specialization, use the linkage for
// the template parameters and arguments.
if (FunctionTemplateSpecializationInfo *spec
@@ -1002,10 +965,14 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
// 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);
- if (!LV.isVisibilityExplicit() && !classLV.isVisibilityExplicit())
- LV.mergeVisibility(typeLV);
- LV.mergeExternalVisibility(typeLV);
+ if (!IgnoreVarTypeLinkage) {
+ LinkageInfo typeLV = getLVForType(*VD->getType(), computation);
+ // FIXME: If the type's linkage is not externally visible, we can
+ // give this static data member UniqueExternalLinkage.
+ if (!LV.isVisibilityExplicit() && !classLV.isVisibilityExplicit())
+ LV.mergeVisibility(typeLV);
+ LV.mergeExternalVisibility(typeLV);
+ }
if (isExplicitMemberSpecialization(VD)) {
explicitSpecSuppressor = VD;
@@ -1047,17 +1014,16 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
return LV;
}
-void NamedDecl::anchor() { }
-
-static LinkageInfo computeLVForDecl(const NamedDecl *D,
- LVComputationKind computation);
+void NamedDecl::anchor() {}
bool NamedDecl::isLinkageValid() const {
if (!hasCachedLinkage())
return true;
- return computeLVForDecl(this, LVForLinkageOnly).getLinkage() ==
- getCachedLinkage();
+ Linkage L = LinkageComputer{}
+ .computeLVForDecl(this, LVComputationKind::forLinkageOnly())
+ .getLinkage();
+ return L == getCachedLinkage();
}
ObjCStringFormatFamily NamedDecl::getObjCFStringFormattingFamily() const {
@@ -1076,13 +1042,13 @@ ObjCStringFormatFamily NamedDecl::getObjCFStringFormattingFamily() const {
Linkage NamedDecl::getLinkageInternal() const {
// We don't care about visibility here, so ask for the cheapest
// possible visibility analysis.
- return getLVForDecl(this, LVForLinkageOnly).getLinkage();
+ return LinkageComputer{}
+ .getLVForDecl(this, LVComputationKind::forLinkageOnly())
+ .getLinkage();
}
LinkageInfo NamedDecl::getLinkageAndVisibility() const {
- LVComputationKind computation =
- (usesTypeVisibility(this) ? LVForType : LVForValue);
- return getLVForDecl(this, computation);
+ return LinkageComputer{}.getDeclLinkageAndVisibility(this);
}
static Optional<Visibility>
@@ -1160,30 +1126,46 @@ NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const {
return getExplicitVisibilityAux(this, kind, false);
}
-static LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
- LVComputationKind computation) {
+LinkageInfo LinkageComputer::getLVForClosure(const DeclContext *DC,
+ Decl *ContextDecl,
+ LVComputationKind computation) {
// This lambda has its linkage/visibility determined by its owner.
- if (ContextDecl) {
- if (isa<ParmVarDecl>(ContextDecl))
- DC = ContextDecl->getDeclContext()->getRedeclContext();
- else
- return getLVForDecl(cast<NamedDecl>(ContextDecl), computation);
- }
+ const NamedDecl *Owner;
+ if (!ContextDecl)
+ Owner = dyn_cast<NamedDecl>(DC);
+ else if (isa<ParmVarDecl>(ContextDecl))
+ Owner =
+ dyn_cast<NamedDecl>(ContextDecl->getDeclContext()->getRedeclContext());
+ else
+ Owner = cast<NamedDecl>(ContextDecl);
- if (const auto *ND = dyn_cast<NamedDecl>(DC))
- return getLVForDecl(ND, computation);
+ if (!Owner)
+ return LinkageInfo::none();
- // FIXME: We have a closure at TU scope with no context declaration. This
- // should probably have no linkage.
- return LinkageInfo::external();
+ // If the owner has a deduced type, we need to skip querying the linkage and
+ // visibility of that type, because it might involve this closure type. The
+ // only effect of this is that we might give a lambda VisibleNoLinkage rather
+ // than NoLinkage when we don't strictly need to, which is benign.
+ auto *VD = dyn_cast<VarDecl>(Owner);
+ LinkageInfo OwnerLV =
+ VD && VD->getType()->getContainedDeducedType()
+ ? computeLVForDecl(Owner, computation, /*IgnoreVarTypeLinkage*/true)
+ : getLVForDecl(Owner, computation);
+
+ // A lambda never formally has linkage. But if the owner is externally
+ // visible, then the lambda is too. We apply the same rules to blocks.
+ if (!isExternallyVisible(OwnerLV.getLinkage()))
+ return LinkageInfo::none();
+ return LinkageInfo(VisibleNoLinkage, OwnerLV.getVisibility(),
+ OwnerLV.isVisibilityExplicit());
}
-static LinkageInfo getLVForLocalDecl(const NamedDecl *D,
- LVComputationKind computation) {
+LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D,
+ LVComputationKind computation) {
if (const auto *Function = dyn_cast<FunctionDecl>(D)) {
if (Function->isInAnonymousNamespace() &&
!Function->isInExternCContext())
- return LinkageInfo::uniqueExternal();
+ return getInternalLinkageFor(Function);
// This is a "void f();" which got merged with a file static.
if (Function->getCanonicalDecl()->getStorageClass() == SC_Static)
@@ -1206,7 +1188,7 @@ static LinkageInfo getLVForLocalDecl(const NamedDecl *D,
if (const auto *Var = dyn_cast<VarDecl>(D)) {
if (Var->hasExternalStorage()) {
if (Var->isInAnonymousNamespace() && !Var->isInExternCContext())
- return LinkageInfo::uniqueExternal();
+ return getInternalLinkageFor(Var);
LinkageInfo LV;
if (Var->getStorageClass() == SC_PrivateExtern)
@@ -1272,8 +1254,9 @@ getOutermostEnclosingLambda(const CXXRecordDecl *Record) {
return Ret;
}
-static LinkageInfo computeLVForDecl(const NamedDecl *D,
- LVComputationKind computation) {
+LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D,
+ LVComputationKind computation,
+ bool IgnoreVarTypeLinkage) {
// Internal_linkage attribute overrides other considerations.
if (D->hasAttr<InternalLinkageAttr>())
return getInternalLinkageFor(D);
@@ -1361,7 +1344,7 @@ static LinkageInfo computeLVForDecl(const NamedDecl *D,
// Handle linkage for namespace-scope names.
if (D->getDeclContext()->getRedeclContext()->isFileContext())
- return getLVForNamespaceScopeDecl(D, computation);
+ return getLVForNamespaceScopeDecl(D, computation, IgnoreVarTypeLinkage);
// C++ [basic.link]p5:
// In addition, a member function, static data member, a named
@@ -1371,7 +1354,7 @@ static LinkageInfo computeLVForDecl(const NamedDecl *D,
// purposes (7.1.3), has external linkage if the name of the class
// has external linkage.
if (D->getDeclContext()->isRecord())
- return getLVForClassMember(D, computation);
+ return getLVForClassMember(D, computation, IgnoreVarTypeLinkage);
// C++ [basic.link]p6:
// The name of a function declared in block scope and the name of
@@ -1392,56 +1375,93 @@ static LinkageInfo computeLVForDecl(const NamedDecl *D,
return LinkageInfo::none();
}
-namespace clang {
-class LinkageComputer {
-public:
- static LinkageInfo getLVForDecl(const NamedDecl *D,
- LVComputationKind computation) {
- // Internal_linkage attribute overrides other considerations.
- if (D->hasAttr<InternalLinkageAttr>())
- return getInternalLinkageFor(D);
+/// getLVForDecl - Get the linkage and visibility for the given declaration.
+LinkageInfo LinkageComputer::getLVForDecl(const NamedDecl *D,
+ LVComputationKind computation) {
+ // Internal_linkage attribute overrides other considerations.
+ if (D->hasAttr<InternalLinkageAttr>())
+ return getInternalLinkageFor(D);
+
+ if (computation.IgnoreAllVisibility && D->hasCachedLinkage())
+ return LinkageInfo(D->getCachedLinkage(), DefaultVisibility, false);
- if (computation == LVForLinkageOnly && D->hasCachedLinkage())
- return LinkageInfo(D->getCachedLinkage(), DefaultVisibility, false);
+ if (llvm::Optional<LinkageInfo> LI = lookup(D, computation))
+ return *LI;
- LinkageInfo LV = computeLVForDecl(D, computation);
- if (D->hasCachedLinkage())
- assert(D->getCachedLinkage() == LV.getLinkage());
+ LinkageInfo LV = computeLVForDecl(D, computation);
+ if (D->hasCachedLinkage())
+ assert(D->getCachedLinkage() == LV.getLinkage());
- D->setCachedLinkage(LV.getLinkage());
+ D->setCachedLinkage(LV.getLinkage());
+ cache(D, computation, LV);
#ifndef NDEBUG
- // In C (because of gnu inline) and in c++ with microsoft extensions an
- // static can follow an extern, so we can have two decls with different
- // linkages.
- const LangOptions &Opts = D->getASTContext().getLangOpts();
- if (!Opts.CPlusPlus || Opts.MicrosoftExt)
- return LV;
+ // In C (because of gnu inline) and in c++ with microsoft extensions an
+ // static can follow an extern, so we can have two decls with different
+ // linkages.
+ const LangOptions &Opts = D->getASTContext().getLangOpts();
+ if (!Opts.CPlusPlus || Opts.MicrosoftExt)
+ return LV;
- // We have just computed the linkage for this decl. By induction we know
- // that all other computed linkages match, check that the one we just
- // computed also does.
- NamedDecl *Old = nullptr;
- for (auto I : D->redecls()) {
- auto *T = cast<NamedDecl>(I);
- if (T == D)
- continue;
- if (!T->isInvalidDecl() && T->hasCachedLinkage()) {
- Old = T;
- break;
- }
+ // We have just computed the linkage for this decl. By induction we know
+ // that all other computed linkages match, check that the one we just
+ // computed also does.
+ NamedDecl *Old = nullptr;
+ for (auto I : D->redecls()) {
+ auto *T = cast<NamedDecl>(I);
+ if (T == D)
+ continue;
+ if (!T->isInvalidDecl() && T->hasCachedLinkage()) {
+ Old = T;
+ break;
}
- assert(!Old || Old->getCachedLinkage() == D->getCachedLinkage());
+ }
+ assert(!Old || Old->getCachedLinkage() == D->getCachedLinkage());
#endif
- return LV;
- }
-};
+ return LV;
}
-static LinkageInfo getLVForDecl(const NamedDecl *D,
- LVComputationKind computation) {
- return clang::LinkageComputer::getLVForDecl(D, computation);
+LinkageInfo LinkageComputer::getDeclLinkageAndVisibility(const NamedDecl *D) {
+ return getLVForDecl(D,
+ LVComputationKind(usesTypeVisibility(D)
+ ? NamedDecl::VisibilityForType
+ : NamedDecl::VisibilityForValue));
+}
+
+Module *Decl::getOwningModuleForLinkage(bool IgnoreLinkage) const {
+ Module *M = getOwningModule();
+ if (!M)
+ return nullptr;
+
+ switch (M->Kind) {
+ case Module::ModuleMapModule:
+ // Module map modules have no special linkage semantics.
+ return nullptr;
+
+ case Module::ModuleInterfaceUnit:
+ return M;
+
+ case Module::GlobalModuleFragment: {
+ // External linkage declarations in the global module have no owning module
+ // for linkage purposes. But internal linkage declarations in the global
+ // module fragment of a particular module are owned by that module for
+ // linkage purposes.
+ if (IgnoreLinkage)
+ return nullptr;
+ bool InternalLinkage;
+ if (auto *ND = dyn_cast<NamedDecl>(this))
+ InternalLinkage = !ND->hasExternalFormalLinkage();
+ else {
+ auto *NSD = dyn_cast<NamespaceDecl>(this);
+ InternalLinkage = (NSD && NSD->isAnonymousNamespace()) ||
+ isInAnonymousNamespace();
+ }
+ return InternalLinkage ? M->Parent : nullptr;
+ }
+ }
+
+ llvm_unreachable("unknown module kind");
}
void NamedDecl::printName(raw_ostream &os) const {
@@ -1473,7 +1493,7 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
return;
}
- typedef SmallVector<const DeclContext *, 8> ContextsTy;
+ using ContextsTy = SmallVector<const DeclContext *, 8>;
ContextsTy Contexts;
// Collect contexts.
@@ -1482,12 +1502,11 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
Ctx = Ctx->getParent();
}
- for (const DeclContext *DC : reverse(Contexts)) {
+ for (const DeclContext *DC : llvm::reverse(Contexts)) {
if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
OS << Spec->getName();
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, TemplateArgs.asArray(), P);
+ printTemplateArgumentList(OS, TemplateArgs.asArray(), P);
} else if (const auto *ND = dyn_cast<NamespaceDecl>(DC)) {
if (P.SuppressUnwrittenScope &&
(ND->isAnonymousNamespace() || ND->isInline()))
@@ -1612,14 +1631,6 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const {
cast<UnresolvedUsingValueDecl>(OldD)->getQualifier());
}
- // UsingDirectiveDecl's are not really NamedDecl's, and all have same name.
- // They can be replaced if they nominate the same namespace.
- // FIXME: Is this true even if they have different module visibility?
- if (auto *UD = dyn_cast<UsingDirectiveDecl>(this))
- return UD->getNominatedNamespace()->getOriginalNamespace() ==
- cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace()
- ->getOriginalNamespace();
-
if (isRedeclarable(getKind())) {
if (getCanonicalDecl() != OldD->getCanonicalDecl())
return false;
@@ -1754,11 +1765,9 @@ SourceLocation DeclaratorDecl::getOuterLocStart() const {
return getTemplateOrInnerLocStart(this);
}
-namespace {
-
// Helper function: returns true if QT is or contains a type
// having a postfix component.
-bool typeIsPostfix(clang::QualType QT) {
+static bool typeIsPostfix(QualType QT) {
while (true) {
const Type* T = QT.getTypePtr();
switch (T->getTypeClass()) {
@@ -1792,8 +1801,6 @@ bool typeIsPostfix(clang::QualType QT) {
}
}
-} // namespace
-
SourceRange DeclaratorDecl::getSourceRange() const {
SourceLocation RangeEnd = getLocation();
if (TypeSourceInfo *TInfo = getTypeSourceInfo()) {
@@ -1843,7 +1850,7 @@ VarDecl::VarDecl(Kind DK, ASTContext &C, DeclContext *DC,
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
StorageClass SC)
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
- redeclarable_base(C), Init() {
+ redeclarable_base(C) {
static_assert(sizeof(VarDeclBitfields) <= sizeof(unsigned),
"VarDeclBitfields too large!");
static_assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned),
@@ -1967,6 +1974,9 @@ VarDecl *VarDecl::getCanonicalDecl() { return getFirstDecl(); }
VarDecl::DefinitionKind
VarDecl::isThisDeclarationADefinition(ASTContext &C) const {
+ if (isThisDeclarationADemotedDefinition())
+ return DeclarationOnly;
+
// C++ [basic.def]p2:
// A declaration is a definition unless [...] it contains the 'extern'
// specifier or a linkage-specification and neither an initializer [...],
@@ -1980,9 +1990,6 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const {
//
// FIXME: How do you declare (but not define) a partial specialization of
// a static data member template outside the containing class?
- if (isThisDeclarationADemotedDefinition())
- return DeclarationOnly;
-
if (isStaticDataMember()) {
if (isOutOfLine() &&
!(getCanonicalDecl()->isInline() &&
@@ -2022,9 +2029,12 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const {
// A variable template specialization (other than a static data member
// template or an explicit specialization) is a declaration until we
// instantiate its initializer.
- if (isa<VarTemplateSpecializationDecl>(this) &&
- getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
- return DeclarationOnly;
+ if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(this)) {
+ if (VTSD->getTemplateSpecializationKind() != TSK_ExplicitSpecialization &&
+ !isa<VarTemplatePartialSpecializationDecl>(VTSD) &&
+ !VTSD->IsCompleteDefinition)
+ return DeclarationOnly;
+ }
if (hasExternalStorage())
return DeclarationOnly;
@@ -2408,15 +2418,21 @@ void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
dyn_cast<VarTemplateSpecializationDecl>(this)) {
Spec->setSpecializationKind(TSK);
if (TSK != TSK_ExplicitSpecialization && PointOfInstantiation.isValid() &&
- Spec->getPointOfInstantiation().isInvalid())
+ Spec->getPointOfInstantiation().isInvalid()) {
Spec->setPointOfInstantiation(PointOfInstantiation);
+ if (ASTMutationListener *L = getASTContext().getASTMutationListener())
+ L->InstantiationRequested(this);
+ }
}
if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) {
MSI->setTemplateSpecializationKind(TSK);
if (TSK != TSK_ExplicitSpecialization && PointOfInstantiation.isValid() &&
- MSI->getPointOfInstantiation().isInvalid())
+ MSI->getPointOfInstantiation().isInvalid()) {
MSI->setPointOfInstantiation(PointOfInstantiation);
+ if (ASTMutationListener *L = getASTContext().getASTMutationListener())
+ L->InstantiationRequested(this);
+ }
}
}
@@ -2548,8 +2564,7 @@ void FunctionDecl::getNameForDiagnostic(
NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs();
if (TemplateArgs)
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, TemplateArgs->asArray(), Policy);
+ printTemplateArgumentList(OS, TemplateArgs->asArray(), Policy);
}
bool FunctionDecl::isVariadic() const {
@@ -2747,6 +2762,20 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction(bool *IsAligned) const
return Params == FPT->getNumParams();
}
+bool FunctionDecl::isDestroyingOperatorDelete() const {
+ // C++ P0722:
+ // Within a class C, a single object deallocation function with signature
+ // (T, std::destroying_delete_t, <more params>)
+ // is a destroying operator delete.
+ if (!isa<CXXMethodDecl>(this) || getOverloadedOperator() != OO_Delete ||
+ getNumParams() < 2)
+ return false;
+
+ auto *RD = getParamDecl(1)->getType()->getAsCXXRecordDecl();
+ return RD && RD->isInStdNamespace() && RD->getIdentifier() &&
+ RD->getIdentifier()->isStr("destroying_delete_t");
+}
+
LanguageLinkage FunctionDecl::getLanguageLinkage() const {
return getDeclLanguageLinkage(*this);
}
@@ -2871,7 +2900,6 @@ unsigned FunctionDecl::getBuiltinID() const {
return BuiltinID;
}
-
/// getNumParams - Return the number of parameters this function must have
/// based on its FunctionType. This is the length of the ParamInfo array
/// after it has been created.
@@ -3057,7 +3085,8 @@ SourceRange FunctionDecl::getExceptionSpecSourceRange() const {
const Attr *FunctionDecl::getUnusedResultAttr() const {
QualType RetType = getReturnType();
if (RetType->isRecordType()) {
- if (const CXXRecordDecl *Ret = RetType->getAsCXXRecordDecl()) {
+ if (const auto *Ret =
+ dyn_cast_or_null<RecordDecl>(RetType->getAsTagDecl())) {
if (const auto *R = Ret->getAttr<WarnUnusedResultAttr>())
return R;
}
@@ -3382,7 +3411,6 @@ DependentFunctionTemplateSpecializationInfo::
DependentFunctionTemplateSpecializationInfo(const UnresolvedSetImpl &Ts,
const TemplateArgumentListInfo &TArgs)
: AngleLocs(TArgs.getLAngleLoc(), TArgs.getRAngleLoc()) {
-
NumTemplates = Ts.size();
NumArgs = TArgs.size();
@@ -3420,15 +3448,21 @@ FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
FTSInfo->setTemplateSpecializationKind(TSK);
if (TSK != TSK_ExplicitSpecialization &&
PointOfInstantiation.isValid() &&
- FTSInfo->getPointOfInstantiation().isInvalid())
+ FTSInfo->getPointOfInstantiation().isInvalid()) {
FTSInfo->setPointOfInstantiation(PointOfInstantiation);
+ if (ASTMutationListener *L = getASTContext().getASTMutationListener())
+ L->InstantiationRequested(this);
+ }
} else if (MemberSpecializationInfo *MSInfo
= TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) {
MSInfo->setTemplateSpecializationKind(TSK);
if (TSK != TSK_ExplicitSpecialization &&
PointOfInstantiation.isValid() &&
- MSInfo->getPointOfInstantiation().isInvalid())
+ MSInfo->getPointOfInstantiation().isInvalid()) {
MSInfo->setPointOfInstantiation(PointOfInstantiation);
+ if (ASTMutationListener *L = getASTContext().getASTMutationListener())
+ L->InstantiationRequested(this);
+ }
} else
llvm_unreachable("Function cannot have a template specialization kind");
}
@@ -3598,8 +3632,7 @@ bool FieldDecl::isAnonymousStructOrUnion() const {
unsigned FieldDecl::getBitWidthValue(const ASTContext &Ctx) const {
assert(isBitField() && "not a bitfield");
- auto *BitWidth = static_cast<Expr *>(InitStorage.getPointer());
- return BitWidth->EvaluateKnownConstInt(Ctx).getZExtValue();
+ return getBitWidth()->EvaluateKnownConstInt(Ctx).getZExtValue();
}
unsigned FieldDecl::getFieldIndex() const {
@@ -3610,7 +3643,8 @@ unsigned FieldDecl::getFieldIndex() const {
if (CachedFieldIndex) return CachedFieldIndex - 1;
unsigned Index = 0;
- const RecordDecl *RD = getParent();
+ const RecordDecl *RD = getParent()->getDefinition();
+ assert(RD && "requested index for field of struct with no definition");
for (auto *Field : RD->fields()) {
Field->getCanonicalDecl()->CachedFieldIndex = Index + 1;
@@ -3622,25 +3656,18 @@ unsigned FieldDecl::getFieldIndex() const {
}
SourceRange FieldDecl::getSourceRange() const {
- switch (InitStorage.getInt()) {
- // All three of these cases store an optional Expr*.
- case ISK_BitWidthOrNothing:
- case ISK_InClassCopyInit:
- case ISK_InClassListInit:
- if (const auto *E = static_cast<const Expr *>(InitStorage.getPointer()))
- return SourceRange(getInnerLocStart(), E->getLocEnd());
- // FALLTHROUGH
-
- case ISK_CapturedVLAType:
- return DeclaratorDecl::getSourceRange();
- }
- llvm_unreachable("bad init storage kind");
+ const Expr *FinalExpr = getInClassInitializer();
+ if (!FinalExpr)
+ FinalExpr = getBitWidth();
+ if (FinalExpr)
+ return SourceRange(getInnerLocStart(), FinalExpr->getLocEnd());
+ return DeclaratorDecl::getSourceRange();
}
void FieldDecl::setCapturedVLAType(const VariableArrayType *VLAType) {
assert((getParent()->isLambda() || getParent()->isCapturedRecord()) &&
"capturing type in non-lambda or captured record.");
- assert(InitStorage.getInt() == ISK_BitWidthOrNothing &&
+ assert(InitStorage.getInt() == ISK_NoInit &&
InitStorage.getPointer() == nullptr &&
"bit width, initializer or captured type already set");
InitStorage.setPointerAndInt(const_cast<VariableArrayType *>(VLAType),
@@ -3753,7 +3780,7 @@ void TagDecl::setTemplateParameterListsInfo(
// EnumDecl Implementation
//===----------------------------------------------------------------------===//
-void EnumDecl::anchor() { }
+void EnumDecl::anchor() {}
EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
@@ -3862,12 +3889,10 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C,
DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
RecordDecl *PrevDecl)
- : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc) {
- HasFlexibleArrayMember = false;
- AnonymousStructOrUnion = false;
- HasObjectMember = false;
- HasVolatileMember = false;
- LoadedFieldsFromExternalStorage = false;
+ : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc),
+ HasFlexibleArrayMember(false), AnonymousStructOrUnion(false),
+ HasObjectMember(false), HasVolatileMember(false),
+ LoadedFieldsFromExternalStorage(false) {
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
}
@@ -3958,9 +3983,9 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const {
ASTContext &Context = getASTContext();
- if (!Context.getLangOpts().Sanitize.hasOneOf(
- SanitizerKind::Address | SanitizerKind::KernelAddress) ||
- !Context.getLangOpts().SanitizeAddressFieldPadding)
+ const SanitizerMask EnabledAsanMask = Context.getLangOpts().Sanitize.Mask &
+ (SanitizerKind::Address | SanitizerKind::KernelAddress);
+ if (!EnabledAsanMask || !Context.getLangOpts().SanitizeAddressFieldPadding)
return false;
const auto &Blacklist = Context.getSanitizerBlacklist();
const auto *CXXRD = dyn_cast<CXXRecordDecl>(this);
@@ -3978,9 +4003,11 @@ bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const {
ReasonToReject = 4; // has trivial destructor.
else if (CXXRD->isStandardLayout())
ReasonToReject = 5; // is standard layout.
- else if (Blacklist.isBlacklistedLocation(getLocation(), "field-padding"))
+ else if (Blacklist.isBlacklistedLocation(EnabledAsanMask, getLocation(),
+ "field-padding"))
ReasonToReject = 6; // is in a blacklisted file.
- else if (Blacklist.isBlacklistedType(getQualifiedNameAsString(),
+ else if (Blacklist.isBlacklistedType(EnabledAsanMask,
+ getQualifiedNameAsString(),
"field-padding"))
ReasonToReject = 7; // is blacklisted.
@@ -4014,7 +4041,6 @@ const FieldDecl *RecordDecl::findFirstNamedDataMember() const {
return nullptr;
}
-
//===----------------------------------------------------------------------===//
// BlockDecl Implementation
//===----------------------------------------------------------------------===//
@@ -4060,13 +4086,13 @@ SourceRange BlockDecl::getSourceRange() const {
// Other Decl Allocation/Deallocation Method Implementations
//===----------------------------------------------------------------------===//
-void TranslationUnitDecl::anchor() { }
+void TranslationUnitDecl::anchor() {}
TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
return new (C, (DeclContext *)nullptr) TranslationUnitDecl(C);
}
-void PragmaCommentDecl::anchor() { }
+void PragmaCommentDecl::anchor() {}
PragmaCommentDecl *PragmaCommentDecl::Create(const ASTContext &C,
TranslationUnitDecl *DC,
@@ -4088,7 +4114,7 @@ PragmaCommentDecl *PragmaCommentDecl::CreateDeserialized(ASTContext &C,
PragmaCommentDecl(nullptr, SourceLocation(), PCK_Unknown);
}
-void PragmaDetectMismatchDecl::anchor() { }
+void PragmaDetectMismatchDecl::anchor() {}
PragmaDetectMismatchDecl *
PragmaDetectMismatchDecl::Create(const ASTContext &C, TranslationUnitDecl *DC,
@@ -4113,14 +4139,14 @@ PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, unsigned ID,
PragmaDetectMismatchDecl(nullptr, SourceLocation(), 0);
}
-void ExternCContextDecl::anchor() { }
+void ExternCContextDecl::anchor() {}
ExternCContextDecl *ExternCContextDecl::Create(const ASTContext &C,
TranslationUnitDecl *DC) {
return new (C, DC) ExternCContextDecl(DC);
}
-void LabelDecl::anchor() { }
+void LabelDecl::anchor() {}
LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation IdentL, IdentifierInfo *II) {
@@ -4146,7 +4172,7 @@ void LabelDecl::setMSAsmLabel(StringRef Name) {
MSAsmName = Buffer;
}
-void ValueDecl::anchor() { }
+void ValueDecl::anchor() {}
bool ValueDecl::isWeak() const {
for (const auto *I : attrs())
@@ -4156,7 +4182,7 @@ bool ValueDecl::isWeak() const {
return isWeakImported();
}
-void ImplicitParamDecl::anchor() { }
+void ImplicitParamDecl::anchor() {}
ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation IdLoc,
@@ -4239,7 +4265,7 @@ EnumConstantDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
QualType(), nullptr, llvm::APSInt());
}
-void IndirectFieldDecl::anchor() { }
+void IndirectFieldDecl::anchor() {}
IndirectFieldDecl::IndirectFieldDecl(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName N,
@@ -4273,7 +4299,7 @@ SourceRange EnumConstantDecl::getSourceRange() const {
return SourceRange(getLocation(), End);
}
-void TypeDecl::anchor() { }
+void TypeDecl::anchor() {}
TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
@@ -4281,7 +4307,7 @@ TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
return new (C, DC) TypedefDecl(C, DC, StartLoc, IdLoc, Id, TInfo);
}
-void TypedefNameDecl::anchor() { }
+void TypedefNameDecl::anchor() {}
TagDecl *TypedefNameDecl::getAnonDeclWithTypedefName(bool AnyRedecl) const {
if (auto *TT = getTypeSourceInfo()->getType()->getAs<TagType>()) {
@@ -4355,7 +4381,7 @@ SourceRange TypeAliasDecl::getSourceRange() const {
return SourceRange(getLocStart(), RangeEnd);
}
-void FileScopeAsmDecl::anchor() { }
+void FileScopeAsmDecl::anchor() {}
FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC,
StringLiteral *Str,
@@ -4398,9 +4424,7 @@ static unsigned getNumModuleIdentifiers(Module *Mod) {
ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
Module *Imported,
ArrayRef<SourceLocation> IdentifierLocs)
- : Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, true),
- NextLocalImport()
-{
+ : Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, true) {
assert(getNumModuleIdentifiers(Imported) == IdentifierLocs.size());
auto *StoredLocs = getTrailingObjects<SourceLocation>();
std::uninitialized_copy(IdentifierLocs.begin(), IdentifierLocs.end(),
@@ -4409,9 +4433,7 @@ ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
Module *Imported, SourceLocation EndLoc)
- : Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, false),
- NextLocalImport()
-{
+ : Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, false) {
*getTrailingObjects<SourceLocation>() = EndLoc;
}