diff options
Diffstat (limited to 'clang/lib/AST/Decl.cpp')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 146 |
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()); |