diff options
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r-- | lib/AST/Decl.cpp | 230 |
1 files changed, 172 insertions, 58 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 8030dd0c2f41a..5536358b1ecf1 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -14,6 +14,7 @@ #include "clang/AST/Decl.h" #include "Linkage.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTDiagnostic.h" #include "clang/AST/ASTLambda.h" #include "clang/AST/ASTMutationListener.h" #include "clang/AST/CanonicalType.h" @@ -49,7 +50,6 @@ #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" @@ -725,7 +725,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, // If we're paying attention to global visibility, apply // -finline-visibility-hidden if this is an inline method. if (useInlineVisibilityHidden(D)) - LV.mergeVisibility(HiddenVisibility, true); + LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false); } } @@ -915,7 +915,7 @@ LinkageComputer::getLVForClassMember(const NamedDecl *D, // Note that we do this before merging information about // the class visibility. if (!LV.isVisibilityExplicit() && useInlineVisibilityHidden(D)) - LV.mergeVisibility(HiddenVisibility, true); + LV.mergeVisibility(HiddenVisibility, /*visibilityExplicit=*/false); } // If this class member has an explicit visibility attribute, the only @@ -1262,7 +1262,27 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D, !isTemplateInstantiation(FD->getTemplateSpecializationKind())) return LinkageInfo::none(); + // If a function is hidden by -fvisibility-inlines-hidden option and + // is not explicitly attributed as a hidden function, + // we should not make static local variables in the function hidden. LV = getLVForDecl(FD, computation); + if (isa<VarDecl>(D) && useInlineVisibilityHidden(FD) && + !LV.isVisibilityExplicit()) { + assert(cast<VarDecl>(D)->isStaticLocal()); + // If this was an implicitly hidden inline method, check again for + // explicit visibility on the parent class, and use that for static locals + // if present. + if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) + LV = getLVForDecl(MD->getParent(), computation); + if (!LV.isVisibilityExplicit()) { + Visibility globalVisibility = + computation.isValueVisibility() + ? Context.getLangOpts().getValueVisibilityMode() + : Context.getLangOpts().getTypeVisibilityMode(); + return LinkageInfo(VisibleNoLinkage, globalVisibility, + /*visibilityExplicit=*/false); + } + } } if (!isExternallyVisible(LV.getLinkage())) return LinkageInfo::none(); @@ -1937,7 +1957,7 @@ VarDecl::TLSKind VarDecl::getTLSKind() const { SourceRange VarDecl::getSourceRange() const { if (const Expr *Init = getInit()) { - SourceLocation InitEnd = Init->getLocEnd(); + SourceLocation InitEnd = Init->getEndLoc(); // If Init is implicit, ignore its source range and fallback on // DeclaratorDecl::getSourceRange() to handle postfix elements. if (InitEnd.isValid() && InitEnd != getLocation()) @@ -2351,6 +2371,14 @@ static DeclT *getDefinitionOrSelf(DeclT *D) { return D; } +bool VarDecl::isEscapingByref() const { + return hasAttr<BlocksAttr>() && NonParmVarDeclBits.EscapingByref; +} + +bool VarDecl::isNonEscapingByref() const { + return hasAttr<BlocksAttr>() && !NonParmVarDeclBits.EscapingByref; +} + VarDecl *VarDecl::getTemplateInstantiationPattern() const { // If it's a variable template specialization, find the template or partial // specialization from which it was instantiated. @@ -2441,7 +2469,7 @@ bool VarDecl::isKnownToBeDefined() const { // // With CUDA relocatable device code enabled, these variables don't get // special handling; they're treated like regular extern variables. - if (LangOpts.CUDA && !LangOpts.CUDARelocatableDeviceCode && + if (LangOpts.CUDA && !LangOpts.GPURelocatableDeviceCode && hasExternalStorage() && hasAttr<CUDASharedAttr>() && isa<IncompleteArrayType>(getType())) return true; @@ -2449,6 +2477,12 @@ bool VarDecl::isKnownToBeDefined() const { return hasDefinition(); } +bool VarDecl::isNoDestroy(const ASTContext &Ctx) const { + return hasGlobalStorage() && (hasAttr<NoDestroyAttr>() || + (!Ctx.getLangOpts().RegisterStaticDestructors && + !hasAttr<AlwaysDestroyAttr>())); +} + MemberSpecializationInfo *VarDecl::getMemberSpecializationInfo() const { if (isStaticDataMember()) // FIXME: Remove ? @@ -2531,7 +2565,7 @@ SourceRange ParmVarDecl::getSourceRange() const { // DeclaratorDecl considers the range of postfix types as overlapping with the // declaration name, but this is not the case with parameters in ObjC methods. if (isa<ObjCMethodDecl>(getDeclContext())) - return SourceRange(DeclaratorDecl::getLocStart(), getLocation()); + return SourceRange(DeclaratorDecl::getBeginLoc(), getLocation()); return DeclaratorDecl::getSourceRange(); } @@ -2542,7 +2576,7 @@ Expr *ParmVarDecl::getDefaultArg() { "Default argument is not yet instantiated!"); Expr *Arg = getInit(); - if (auto *E = dyn_cast_or_null<ExprWithCleanups>(Arg)) + if (auto *E = dyn_cast_or_null<FullExpr>(Arg)) return E->getSubExpr(); return Arg; @@ -2609,6 +2643,41 @@ unsigned ParmVarDecl::getParameterIndexLarge() const { // FunctionDecl Implementation //===----------------------------------------------------------------------===// +FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, StorageClass S, + bool isInlineSpecified, bool isConstexprSpecified) + : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, + StartLoc), + DeclContext(DK), redeclarable_base(C), ODRHash(0), + EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) { + assert(T.isNull() || T->isFunctionType()); + FunctionDeclBits.SClass = S; + FunctionDeclBits.IsInline = isInlineSpecified; + FunctionDeclBits.IsInlineSpecified = isInlineSpecified; + FunctionDeclBits.IsExplicitSpecified = false; + FunctionDeclBits.IsVirtualAsWritten = false; + FunctionDeclBits.IsPure = false; + FunctionDeclBits.HasInheritedPrototype = false; + FunctionDeclBits.HasWrittenPrototype = true; + FunctionDeclBits.IsDeleted = false; + FunctionDeclBits.IsTrivial = false; + FunctionDeclBits.IsTrivialForCall = false; + FunctionDeclBits.IsDefaulted = false; + FunctionDeclBits.IsExplicitlyDefaulted = false; + FunctionDeclBits.HasImplicitReturnZero = false; + FunctionDeclBits.IsLateTemplateParsed = false; + FunctionDeclBits.IsConstexpr = isConstexprSpecified; + FunctionDeclBits.InstantiationIsPending = false; + FunctionDeclBits.UsesSEHTry = false; + FunctionDeclBits.HasSkippedBody = false; + FunctionDeclBits.WillHaveBody = false; + FunctionDeclBits.IsMultiVersion = false; + FunctionDeclBits.IsCopyDeductionCandidate = false; + FunctionDeclBits.HasODRHash = false; +} + void FunctionDecl::getNameForDiagnostic( raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); @@ -2672,11 +2741,11 @@ Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const { void FunctionDecl::setBody(Stmt *B) { Body = B; if (B) - EndRangeLoc = B->getLocEnd(); + EndRangeLoc = B->getEndLoc(); } void FunctionDecl::setPure(bool P) { - IsPure = P; + FunctionDeclBits.IsPure = P; if (P) if (auto *Parent = dyn_cast<CXXRecordDecl>(getDeclContext())) Parent->markedVirtualFunctionPure(); @@ -2873,6 +2942,17 @@ bool FunctionDecl::isNoReturn() const { return false; } + +MultiVersionKind FunctionDecl::getMultiVersionKind() const { + if (hasAttr<TargetAttr>()) + return MultiVersionKind::Target; + if (hasAttr<CPUDispatchAttr>()) + return MultiVersionKind::CPUDispatch; + if (hasAttr<CPUSpecificAttr>()) + return MultiVersionKind::CPUSpecific; + return MultiVersionKind::None; +} + bool FunctionDecl::isCPUDispatchMultiVersion() const { return isMultiVersion() && hasAttr<CPUDispatchAttr>(); } @@ -2881,6 +2961,10 @@ bool FunctionDecl::isCPUSpecificMultiVersion() const { return isMultiVersion() && hasAttr<CPUSpecificAttr>(); } +bool FunctionDecl::isTargetMultiVersion() const { + return isMultiVersion() && hasAttr<TargetAttr>(); +} + void FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) { redeclarable_base::setPreviousDecl(PrevDecl); @@ -2892,8 +2976,8 @@ FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) { FunTmpl->setPreviousDecl(PrevFunTmpl); } - if (PrevDecl && PrevDecl->IsInline) - IsInline = true; + if (PrevDecl && PrevDecl->isInlined()) + setImplicitlyInline(true); } FunctionDecl *FunctionDecl::getCanonicalDecl() { return getFirstDecl(); } @@ -3127,7 +3211,7 @@ SourceRange FunctionDecl::getReturnTypeSourceRange() const { // Skip self-referential return types. const SourceManager &SM = getASTContext().getSourceManager(); SourceRange RTRange = FTL.getReturnLoc().getSourceRange(); - SourceLocation Boundary = getNameInfo().getLocStart(); + SourceLocation Boundary = getNameInfo().getBeginLoc(); if (RTRange.isInvalid() || Boundary.isInvalid() || !SM.isBeforeInTranslationUnit(RTRange.getEnd(), Boundary)) return SourceRange(); @@ -3147,20 +3231,6 @@ SourceRange FunctionDecl::getExceptionSpecSourceRange() const { return FTL.getExceptionSpecRange(); } -const Attr *FunctionDecl::getUnusedResultAttr() const { - QualType RetType = getReturnType(); - if (const auto *Ret = RetType->getAsRecordDecl()) { - if (const auto *R = Ret->getAttr<WarnUnusedResultAttr>()) - return R; - } else if (const auto *ET = RetType->getAs<EnumType>()) { - if (const EnumDecl *ED = ET->getDecl()) { - if (const auto *R = ED->getAttr<WarnUnusedResultAttr>()) - return R; - } - } - return getAttr<WarnUnusedResultAttr>(); -} - /// For an inline function definition in C, or for a gnu_inline function /// in C++, determine whether the definition will be externally visible. /// @@ -3664,23 +3734,23 @@ unsigned FunctionDecl::getMemoryFunctionKind() const { } unsigned FunctionDecl::getODRHash() const { - assert(HasODRHash); + assert(hasODRHash()); return ODRHash; } unsigned FunctionDecl::getODRHash() { - if (HasODRHash) + if (hasODRHash()) return ODRHash; if (auto *FT = getInstantiatedFromMemberFunction()) { - HasODRHash = true; + setHasODRHash(true); ODRHash = FT->getODRHash(); return ODRHash; } class ODRHash Hash; Hash.AddFunctionDecl(this); - HasODRHash = true; + setHasODRHash(true); ODRHash = Hash.CalculateHash(); return ODRHash; } @@ -3749,7 +3819,7 @@ SourceRange FieldDecl::getSourceRange() const { if (!FinalExpr) FinalExpr = getBitWidth(); if (FinalExpr) - return SourceRange(getInnerLocStart(), FinalExpr->getLocEnd()); + return SourceRange(getInnerLocStart(), FinalExpr->getEndLoc()); return DeclaratorDecl::getSourceRange(); } @@ -3767,6 +3837,22 @@ void FieldDecl::setCapturedVLAType(const VariableArrayType *VLAType) { // TagDecl Implementation //===----------------------------------------------------------------------===// +TagDecl::TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, + SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl, + SourceLocation StartL) + : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C), + TypedefNameDeclOrQualifier((TypedefNameDecl *)nullptr) { + assert((DK != Enum || TK == TTK_Enum) && + "EnumDecl not matched with TTK_Enum"); + setPreviousDecl(PrevDecl); + setTagKind(TK); + setCompleteDefinition(false); + setBeingDefined(false); + setEmbeddedInDeclarator(false); + setFreeStanding(false); + setCompleteDefinitionRequired(false); +} + SourceLocation TagDecl::getOuterLocStart() const { return getTemplateOrInnerLocStart(this); } @@ -3789,7 +3875,7 @@ void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) { } void TagDecl::startDefinition() { - IsBeingDefined = true; + setBeingDefined(true); if (auto *D = dyn_cast<CXXRecordDecl>(this)) { struct CXXRecordDecl::DefinitionData *Data = @@ -3804,8 +3890,8 @@ void TagDecl::completeDefinition() { cast<CXXRecordDecl>(this)->hasDefinition()) && "definition completed but not started"); - IsCompleteDefinition = true; - IsBeingDefined = false; + setCompleteDefinition(true); + setBeingDefined(false); if (ASTMutationListener *L = getASTMutationListener()) L->CompletedTagDefinition(this); @@ -3816,7 +3902,7 @@ TagDecl *TagDecl::getDefinition() const { return const_cast<TagDecl *>(this); // If it's possible for us to have an out-of-date definition, check now. - if (MayHaveOutOfDateDef) { + if (mayHaveOutOfDateDef()) { if (IdentifierInfo *II = getIdentifier()) { if (II->isOutOfDate()) { updateOutOfDate(*II); @@ -3869,6 +3955,21 @@ void TagDecl::setTemplateParameterListsInfo( // EnumDecl Implementation //===----------------------------------------------------------------------===// +EnumDecl::EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl, + bool Scoped, bool ScopedUsingClassTag, bool Fixed) + : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc) { + assert(Scoped || !ScopedUsingClassTag); + IntegerType = nullptr; + setNumPositiveBits(0); + setNumNegativeBits(0); + setScoped(Scoped); + setScopedUsingClassTag(ScopedUsingClassTag); + setFixed(Fixed); + setHasODRHash(false); + ODRHash = 0; +} + void EnumDecl::anchor() {} EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, @@ -3878,7 +3979,7 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, bool IsScopedUsingClassTag, bool IsFixed) { auto *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl, IsScoped, IsScopedUsingClassTag, IsFixed); - Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules; + Enum->setMayHaveOutOfDateDef(C.getLangOpts().Modules); C.getTypeDeclType(Enum, PrevDecl); return Enum; } @@ -3887,7 +3988,7 @@ EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, unsigned ID) { EnumDecl *Enum = new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr, false, false, false); - Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules; + Enum->setMayHaveOutOfDateDef(C.getLangOpts().Modules); return Enum; } @@ -3971,12 +4072,12 @@ void EnumDecl::setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED, } unsigned EnumDecl::getODRHash() { - if (HasODRHash) + if (hasODRHash()) return ODRHash; class ODRHash Hash; Hash.AddEnumDecl(this); - HasODRHash = true; + setHasODRHash(true); ODRHash = Hash.CalculateHash(); return ODRHash; } @@ -3989,14 +4090,18 @@ 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), - NonTrivialToPrimitiveDefaultInitialize(false), - NonTrivialToPrimitiveCopy(false), NonTrivialToPrimitiveDestroy(false), - ParamDestroyedInCallee(false), ArgPassingRestrictions(APK_CanPassInRegs) { - assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!"); + : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc) { + assert(classof(static_cast<Decl *>(this)) && "Invalid Kind!"); + setHasFlexibleArrayMember(false); + setAnonymousStructOrUnion(false); + setHasObjectMember(false); + setHasVolatileMember(false); + setHasLoadedFieldsFromExternalStorage(false); + setNonTrivialToPrimitiveDefaultInitialize(false); + setNonTrivialToPrimitiveCopy(false); + setNonTrivialToPrimitiveDestroy(false); + setParamDestroyedInCallee(false); + setArgPassingRestrictions(APK_CanPassInRegs); } RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC, @@ -4004,7 +4109,7 @@ RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC, IdentifierInfo *Id, RecordDecl* PrevDecl) { RecordDecl *R = new (C, DC) RecordDecl(Record, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl); - R->MayHaveOutOfDateDef = C.getLangOpts().Modules; + R->setMayHaveOutOfDateDef(C.getLangOpts().Modules); C.getTypeDeclType(R, PrevDecl); return R; @@ -4014,7 +4119,7 @@ RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { RecordDecl *R = new (C, ID) RecordDecl(Record, TTK_Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); - R->MayHaveOutOfDateDef = C.getLangOpts().Modules; + R->setMayHaveOutOfDateDef(C.getLangOpts().Modules); return R; } @@ -4038,7 +4143,7 @@ void RecordDecl::setCapturedRecord() { } RecordDecl::field_iterator RecordDecl::field_begin() const { - if (hasExternalLexicalStorage() && !LoadedFieldsFromExternalStorage) + if (hasExternalLexicalStorage() && !hasLoadedFieldsFromExternalStorage()) LoadFieldsFromExternalStorage(); return field_iterator(decl_iterator(FirstDecl)); @@ -4066,7 +4171,7 @@ void RecordDecl::LoadFieldsFromExternalStorage() const { ExternalASTSource::Deserializing TheFields(Source); SmallVector<Decl*, 64> Decls; - LoadedFieldsFromExternalStorage = true; + setHasLoadedFieldsFromExternalStorage(true); Source->FindExternalLexicalDecls(this, [](Decl::Kind K) { return FieldDecl::classofKind(K) || IndirectFieldDecl::classofKind(K); }, Decls); @@ -4148,6 +4253,15 @@ const FieldDecl *RecordDecl::findFirstNamedDataMember() const { // BlockDecl Implementation //===----------------------------------------------------------------------===// +BlockDecl::BlockDecl(DeclContext *DC, SourceLocation CaretLoc) + : Decl(Block, DC, CaretLoc), DeclContext(Block) { + setIsVariadic(false); + setCapturesCXXThis(false); + setBlockMissingReturnType(true); + setIsConversionFromLambda(false); + setDoesNotEscape(false); +} + void BlockDecl::setParams(ArrayRef<ParmVarDecl *> NewParamInfo) { assert(!ParamInfo && "Already has param info!"); @@ -4161,7 +4275,7 @@ void BlockDecl::setParams(ArrayRef<ParmVarDecl *> NewParamInfo) { void BlockDecl::setCaptures(ASTContext &Context, ArrayRef<Capture> Captures, bool CapturesCXXThis) { - this->CapturesCXXThis = CapturesCXXThis; + this->setCapturesCXXThis(CapturesCXXThis); this->NumCaptures = Captures.size(); if (Captures.empty()) { @@ -4182,7 +4296,7 @@ bool BlockDecl::capturesVariable(const VarDecl *variable) const { } SourceRange BlockDecl::getSourceRange() const { - return SourceRange(getLocation(), Body? Body->getLocEnd() : getLocation()); + return SourceRange(getLocation(), Body ? Body->getEndLoc() : getLocation()); } //===----------------------------------------------------------------------===// @@ -4315,7 +4429,7 @@ FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, FunctionDecl *New = new (C, DC) FunctionDecl(Function, C, DC, StartLoc, NameInfo, T, TInfo, SC, isInlineSpecified, isConstexprSpecified); - New->HasWrittenPrototype = hasWrittenPrototype; + New->setHasWrittenPrototype(hasWrittenPrototype); return New; } @@ -4398,7 +4512,7 @@ IndirectFieldDecl *IndirectFieldDecl::CreateDeserialized(ASTContext &C, SourceRange EnumConstantDecl::getSourceRange() const { SourceLocation End = getLocation(); if (Init) - End = Init->getLocEnd(); + End = Init->getEndLoc(); return SourceRange(getLocation(), End); } @@ -4472,14 +4586,14 @@ SourceRange TypedefDecl::getSourceRange() const { if (typeIsPostfix(TInfo->getType())) RangeEnd = TInfo->getTypeLoc().getSourceRange().getEnd(); } - return SourceRange(getLocStart(), RangeEnd); + return SourceRange(getBeginLoc(), RangeEnd); } SourceRange TypeAliasDecl::getSourceRange() const { - SourceLocation RangeEnd = getLocStart(); + SourceLocation RangeEnd = getBeginLoc(); if (TypeSourceInfo *TInfo = getTypeSourceInfo()) RangeEnd = TInfo->getTypeLoc().getSourceRange().getEnd(); - return SourceRange(getLocStart(), RangeEnd); + return SourceRange(getBeginLoc(), RangeEnd); } void FileScopeAsmDecl::anchor() {} |