summaryrefslogtreecommitdiff
path: root/clang/lib/AST/Decl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/Decl.cpp')
-rw-r--r--clang/lib/AST/Decl.cpp146
1 files changed, 90 insertions, 56 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 0d30f64b992e0..5c0a98815dd79 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -892,6 +892,10 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
if (!TD->getAnonDeclWithTypedefName(/*AnyRedecl*/true))
return LinkageInfo::none();
+ } else if (isa<MSGuidDecl>(D)) {
+ // A GUID behaves like an inline variable with external linkage. Fall
+ // through.
+
// Everything not covered here has no linkage.
} else {
return LinkageInfo::none();
@@ -1318,19 +1322,6 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D,
LV.isVisibilityExplicit());
}
-static inline const CXXRecordDecl*
-getOutermostEnclosingLambda(const CXXRecordDecl *Record) {
- const CXXRecordDecl *Ret = Record;
- while (Record && Record->isLambda()) {
- Ret = Record;
- if (!Record->getParent()) break;
- // Get the Containing Class of this Lambda Class
- Record = dyn_cast_or_null<CXXRecordDecl>(
- Record->getParent()->getParent());
- }
- return Ret;
-}
-
LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D,
LVComputationKind computation,
bool IgnoreVarTypeLinkage) {
@@ -1396,25 +1387,9 @@ LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D,
return getInternalLinkageFor(D);
}
- // This lambda has its linkage/visibility determined:
- // - either by the outermost lambda if that lambda has no mangling
- // number.
- // - or by the parent of the outer most lambda
- // This prevents infinite recursion in settings such as nested lambdas
- // used in NSDMI's, for e.g.
- // struct L {
- // int t{};
- // int t2 = ([](int a) { return [](int b) { return b; };})(t)(t);
- // };
- const CXXRecordDecl *OuterMostLambda =
- getOutermostEnclosingLambda(Record);
- if (OuterMostLambda->hasKnownLambdaInternalLinkage() ||
- !OuterMostLambda->getLambdaManglingNumber())
- return getInternalLinkageFor(D);
-
return getLVForClosure(
- OuterMostLambda->getDeclContext()->getRedeclContext(),
- OuterMostLambda->getLambdaContextDecl(), computation);
+ Record->getDeclContext()->getRedeclContext(),
+ Record->getLambdaContextDecl(), computation);
}
break;
@@ -1571,10 +1546,19 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
return;
}
printNestedNameSpecifier(OS, P);
- if (getDeclName() || isa<DecompositionDecl>(this))
+ if (getDeclName())
OS << *this;
- else
- OS << "(anonymous)";
+ else {
+ // Give the printName override a chance to pick a different name before we
+ // fall back to "(anonymous)".
+ SmallString<64> NameBuffer;
+ llvm::raw_svector_ostream NameOS(NameBuffer);
+ printName(NameOS);
+ if (NameBuffer.empty())
+ OS << "(anonymous)";
+ else
+ OS << NameBuffer;
+ }
}
void NamedDecl::printNestedNameSpecifier(raw_ostream &OS) const {
@@ -1587,13 +1571,16 @@ void NamedDecl::printNestedNameSpecifier(raw_ostream &OS,
// For ObjC methods and properties, look through categories and use the
// interface as context.
- if (auto *MD = dyn_cast<ObjCMethodDecl>(this))
+ if (auto *MD = dyn_cast<ObjCMethodDecl>(this)) {
if (auto *ID = MD->getClassInterface())
Ctx = ID;
- if (auto *PD = dyn_cast<ObjCPropertyDecl>(this)) {
+ } else if (auto *PD = dyn_cast<ObjCPropertyDecl>(this)) {
if (auto *MD = PD->getGetterMethodDecl())
if (auto *ID = MD->getClassInterface())
Ctx = ID;
+ } else if (auto *ID = dyn_cast<ObjCIvarDecl>(this)) {
+ if (auto *CI = ID->getContainingInterface())
+ Ctx = CI;
}
if (Ctx->isFunctionOrMethod())
@@ -2981,7 +2968,8 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const {
return (proto->getParamType(1).getCanonicalType() == Context.VoidPtrTy);
}
-bool FunctionDecl::isReplaceableGlobalAllocationFunction(bool *IsAligned) const {
+bool FunctionDecl::isReplaceableGlobalAllocationFunction(
+ Optional<unsigned> *AlignmentParam, bool *IsNothrow) const {
if (getDeclName().getNameKind() != DeclarationName::CXXOperatorName)
return false;
if (getDeclName().getCXXOverloadedOperator() != OO_New &&
@@ -3028,9 +3016,9 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction(bool *IsAligned) const
// In C++17, the next parameter can be a 'std::align_val_t' for aligned
// new/delete.
if (Ctx.getLangOpts().AlignedAllocation && !Ty.isNull() && Ty->isAlignValT()) {
- if (IsAligned)
- *IsAligned = true;
Consume();
+ if (AlignmentParam)
+ *AlignmentParam = Params;
}
// Finally, if this is not a sized delete, the final parameter can
@@ -3039,8 +3027,11 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction(bool *IsAligned) const
Ty = Ty->getPointeeType();
if (Ty.getCVRQualifiers() != Qualifiers::Const)
return false;
- if (Ty->isNothrowT())
+ if (Ty->isNothrowT()) {
+ if (IsNothrow)
+ *IsNothrow = true;
Consume();
+ }
}
return Params == FPT->getNumParams();
@@ -3173,8 +3164,8 @@ FunctionDecl *FunctionDecl::getCanonicalDecl() { return getFirstDecl(); }
unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const {
unsigned BuiltinID;
- if (const auto *AMAA = getAttr<ArmMveAliasAttr>()) {
- BuiltinID = AMAA->getBuiltinName()->getBuiltinID();
+ if (const auto *ABAA = getAttr<ArmBuiltinAliasAttr>()) {
+ BuiltinID = ABAA->getBuiltinName()->getBuiltinID();
} else {
if (!getIdentifier())
return 0;
@@ -3206,7 +3197,7 @@ unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const {
// If the function is marked "overloadable", it has a different mangled name
// and is not the C library function.
if (!ConsiderWrapperFunctions && hasAttr<OverloadableAttr>() &&
- !hasAttr<ArmMveAliasAttr>())
+ !hasAttr<ArmBuiltinAliasAttr>())
return 0;
if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
@@ -3233,6 +3224,15 @@ unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const {
!(BuiltinID == Builtin::BIprintf || BuiltinID == Builtin::BImalloc))
return 0;
+ // As AMDGCN implementation of OpenMP does not have a device-side standard
+ // library, none of the predefined library functions except printf and malloc
+ // should be treated as a builtin i.e. 0 should be returned for them.
+ if (Context.getTargetInfo().getTriple().isAMDGCN() &&
+ Context.getLangOpts().OpenMPIsDevice &&
+ Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID) &&
+ !(BuiltinID == Builtin::BIprintf || BuiltinID == Builtin::BImalloc))
+ return 0;
+
return BuiltinID;
}
@@ -3264,13 +3264,27 @@ unsigned FunctionDecl::getMinRequiredArguments() const {
if (!getASTContext().getLangOpts().CPlusPlus)
return getNumParams();
+ // Note that it is possible for a parameter with no default argument to
+ // follow a parameter with a default argument.
unsigned NumRequiredArgs = 0;
- for (auto *Param : parameters())
- if (!Param->isParameterPack() && !Param->hasDefaultArg())
- ++NumRequiredArgs;
+ unsigned MinParamsSoFar = 0;
+ for (auto *Param : parameters()) {
+ if (!Param->isParameterPack()) {
+ ++MinParamsSoFar;
+ if (!Param->hasDefaultArg())
+ NumRequiredArgs = MinParamsSoFar;
+ }
+ }
return NumRequiredArgs;
}
+bool FunctionDecl::hasOneParamOrDefaultArgs() const {
+ return getNumParams() == 1 ||
+ (getNumParams() > 1 &&
+ std::all_of(param_begin() + 1, param_end(),
+ [](ParmVarDecl *P) { return P->hasDefaultArg(); }));
+}
+
/// The combination of the extern and inline keywords under MSVC forces
/// the function to be required.
///
@@ -3609,7 +3623,8 @@ bool FunctionDecl::isTemplateInstantiation() const {
return clang::isTemplateInstantiation(getTemplateSpecializationKind());
}
-FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
+FunctionDecl *
+FunctionDecl::getTemplateInstantiationPattern(bool ForDefinition) const {
// If this is a generic lambda call operator specialization, its
// instantiation pattern is always its primary template's pattern
// even if its primary template was instantiated from another
@@ -3626,18 +3641,20 @@ FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
}
if (MemberSpecializationInfo *Info = getMemberSpecializationInfo()) {
- if (!clang::isTemplateInstantiation(Info->getTemplateSpecializationKind()))
+ if (ForDefinition &&
+ !clang::isTemplateInstantiation(Info->getTemplateSpecializationKind()))
return nullptr;
return getDefinitionOrSelf(cast<FunctionDecl>(Info->getInstantiatedFrom()));
}
- if (!clang::isTemplateInstantiation(getTemplateSpecializationKind()))
+ if (ForDefinition &&
+ !clang::isTemplateInstantiation(getTemplateSpecializationKind()))
return nullptr;
if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
// If we hit a point where the user provided a specialization of this
// template, we're done looking.
- while (!Primary->isMemberSpecialization()) {
+ while (!ForDefinition || !Primary->isMemberSpecialization()) {
auto *NewPrimary = Primary->getInstantiatedFromMemberTemplate();
if (!NewPrimary)
break;
@@ -4422,6 +4439,21 @@ void RecordDecl::setCapturedRecord() {
addAttr(CapturedRecordAttr::CreateImplicit(getASTContext()));
}
+bool RecordDecl::isOrContainsUnion() const {
+ if (isUnion())
+ return true;
+
+ if (const RecordDecl *Def = getDefinition()) {
+ for (const FieldDecl *FD : Def->fields()) {
+ const RecordType *RT = FD->getType()->getAs<RecordType>();
+ if (RT && RT->getDecl()->isOrContainsUnion())
+ return true;
+ }
+ }
+
+ return false;
+}
+
RecordDecl::field_iterator RecordDecl::field_begin() const {
if (hasExternalLexicalStorage() && !hasLoadedFieldsFromExternalStorage())
LoadFieldsFromExternalStorage();
@@ -4493,11 +4525,11 @@ bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const {
ReasonToReject = 5; // is standard layout.
else if (Blacklist.isBlacklistedLocation(EnabledAsanMask, getLocation(),
"field-padding"))
- ReasonToReject = 6; // is in a blacklisted file.
+ ReasonToReject = 6; // is in an excluded file.
else if (Blacklist.isBlacklistedType(EnabledAsanMask,
getQualifiedNameAsString(),
"field-padding"))
- ReasonToReject = 7; // is blacklisted.
+ ReasonToReject = 7; // The type is excluded.
if (EmitRemark) {
if (ReasonToReject >= 0)
@@ -4921,7 +4953,8 @@ static unsigned getNumModuleIdentifiers(Module *Mod) {
ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
Module *Imported,
ArrayRef<SourceLocation> IdentifierLocs)
- : Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, true) {
+ : Decl(Import, DC, StartLoc), ImportedModule(Imported),
+ NextLocalImportAndComplete(nullptr, true) {
assert(getNumModuleIdentifiers(Imported) == IdentifierLocs.size());
auto *StoredLocs = getTrailingObjects<SourceLocation>();
std::uninitialized_copy(IdentifierLocs.begin(), IdentifierLocs.end(),
@@ -4930,7 +4963,8 @@ ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
Module *Imported, SourceLocation EndLoc)
- : Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, false) {
+ : Decl(Import, DC, StartLoc), ImportedModule(Imported),
+ NextLocalImportAndComplete(nullptr, false) {
*getTrailingObjects<SourceLocation>() = EndLoc;
}
@@ -4959,7 +4993,7 @@ ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, unsigned ID,
}
ArrayRef<SourceLocation> ImportDecl::getIdentifierLocs() const {
- if (!ImportedAndComplete.getInt())
+ if (!isImportComplete())
return None;
const auto *StoredLocs = getTrailingObjects<SourceLocation>();
@@ -4968,7 +5002,7 @@ ArrayRef<SourceLocation> ImportDecl::getIdentifierLocs() const {
}
SourceRange ImportDecl::getSourceRange() const {
- if (!ImportedAndComplete.getInt())
+ if (!isImportComplete())
return SourceRange(getLocation(), *getTrailingObjects<SourceLocation>());
return SourceRange(getLocation(), getIdentifierLocs().back());