diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 |
commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /clang/lib/AST/Decl.cpp | |
parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) |
Diffstat (limited to 'clang/lib/AST/Decl.cpp')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 258 |
1 files changed, 201 insertions, 57 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index aaba4345587b..e60cc28f6e0f 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -54,8 +54,6 @@ #include "clang/Basic/Visibility.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/StringRef.h" @@ -69,6 +67,7 @@ #include <cstddef> #include <cstring> #include <memory> +#include <optional> #include <string> #include <tuple> #include <type_traits> @@ -170,8 +169,8 @@ withExplicitVisibilityAlready(LVComputationKind Kind) { return Kind; } -static Optional<Visibility> getExplicitVisibility(const NamedDecl *D, - LVComputationKind kind) { +static std::optional<Visibility> getExplicitVisibility(const NamedDecl *D, + LVComputationKind kind) { assert(!kind.IgnoreExplicitVisibility && "asking for explicit visibility when we shouldn't be"); return D->getExplicitVisibility(kind.getExplicitVisibilityKind()); @@ -187,8 +186,8 @@ static bool usesTypeVisibility(const NamedDecl *D) { /// Does the given declaration have member specialization information, /// and if so, is it an explicit specialization? -template <class T> static typename -std::enable_if<!std::is_base_of<RedeclarableTemplateDecl, T>::value, bool>::type +template <class T> +static std::enable_if_t<!std::is_base_of_v<RedeclarableTemplateDecl, T>, bool> isExplicitMemberSpecialization(const T *D) { if (const MemberSpecializationInfo *member = D->getMemberSpecializationInfo()) { @@ -220,8 +219,8 @@ static Visibility getVisibilityFromAttr(const T *attr) { } /// Return the explicit visibility of the given declaration. -static Optional<Visibility> getVisibilityOf(const NamedDecl *D, - NamedDecl::ExplicitVisibilityKind kind) { +static std::optional<Visibility> +getVisibilityOf(const NamedDecl *D, NamedDecl::ExplicitVisibilityKind kind) { // If we're ultimately computing the visibility of a type, look for // a 'type_visibility' attribute before looking for 'visibility'. if (kind == NamedDecl::VisibilityForType) { @@ -235,7 +234,7 @@ static Optional<Visibility> getVisibilityOf(const NamedDecl *D, return getVisibilityFromAttr(A); } - return None; + return std::nullopt; } LinkageInfo LinkageComputer::getLVForType(const Type &T, @@ -729,7 +728,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, LinkageInfo LV = getExternalLinkageFor(D); if (!hasExplicitVisibilityAlready(computation)) { - if (Optional<Visibility> Vis = getExplicitVisibility(D, computation)) { + if (std::optional<Visibility> Vis = getExplicitVisibility(D, computation)) { LV.mergeVisibility(*Vis, true); } else { // If we're declared in a namespace with a visibility attribute, @@ -739,7 +738,8 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, DC = DC->getParent()) { const auto *ND = dyn_cast<NamespaceDecl>(DC); if (!ND) continue; - if (Optional<Visibility> Vis = getExplicitVisibility(ND, computation)) { + if (std::optional<Visibility> Vis = + getExplicitVisibility(ND, computation)) { LV.mergeVisibility(*Vis, true); break; } @@ -834,6 +834,15 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, if (Function->getStorageClass() == SC_PrivateExtern) LV.mergeVisibility(HiddenVisibility, true); + // OpenMP target declare device functions are not callable from the host so + // they should not be exported from the device image. This applies to all + // functions as the host-callable kernel functions are emitted at codegen. + if (Context.getLangOpts().OpenMP && Context.getLangOpts().OpenMPIsDevice && + ((Context.getTargetInfo().getTriple().isAMDGPU() || + Context.getTargetInfo().getTriple().isNVPTX()) || + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(Function))) + LV.mergeVisibility(HiddenVisibility, /*newExplicit=*/false); + // Note that Sema::MergeCompatibleFunctionDecls already takes care of // merging storage classes and visibility attributes, so we don't have to // look at previous decls in here. @@ -956,7 +965,7 @@ LinkageComputer::getLVForClassMember(const NamedDecl *D, // If we have an explicit visibility attribute, merge that in. if (!hasExplicitVisibilityAlready(computation)) { - if (Optional<Visibility> Vis = getExplicitVisibility(D, computation)) + if (std::optional<Visibility> Vis = getExplicitVisibility(D, computation)) LV.mergeVisibility(*Vis, true); // If we're paying attention to global visibility, apply // -finline-visibility-hidden if this is an inline method. @@ -1012,6 +1021,16 @@ LinkageComputer::getLVForClassMember(const NamedDecl *D, explicitSpecSuppressor = MD; } + // OpenMP target declare device functions are not callable from the host so + // they should not be exported from the device image. This applies to all + // functions as the host-callable kernel functions are emitted at codegen. + ASTContext &Context = D->getASTContext(); + if (Context.getLangOpts().OpenMP && Context.getLangOpts().OpenMPIsDevice && + ((Context.getTargetInfo().getTriple().isAMDGPU() || + Context.getTargetInfo().getTriple().isNVPTX()) || + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(MD))) + LV.mergeVisibility(HiddenVisibility, /*newExplicit=*/false); + } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) { if (const auto *spec = dyn_cast<ClassTemplateSpecializationDecl>(RD)) { mergeTemplateLV(LV, spec, computation); @@ -1158,14 +1177,14 @@ LinkageInfo NamedDecl::getLinkageAndVisibility() const { return LinkageComputer{}.getDeclLinkageAndVisibility(this); } -static Optional<Visibility> +static std::optional<Visibility> getExplicitVisibilityAux(const NamedDecl *ND, NamedDecl::ExplicitVisibilityKind kind, bool IsMostRecent) { assert(!IsMostRecent || ND == ND->getMostRecentDecl()); // Check the declaration itself first. - if (Optional<Visibility> V = getVisibilityOf(ND, kind)) + if (std::optional<Visibility> V = getVisibilityOf(ND, kind)) return V; // If this is a member class of a specialization of a class template @@ -1185,11 +1204,11 @@ getExplicitVisibilityAux(const NamedDecl *ND, const auto *TD = spec->getSpecializedTemplate()->getTemplatedDecl(); while (TD != nullptr) { auto Vis = getVisibilityOf(TD, kind); - if (Vis != None) + if (Vis != std::nullopt) return Vis; TD = TD->getPreviousDecl(); } - return None; + return std::nullopt; } // Use the most recent declaration. @@ -1210,7 +1229,7 @@ getExplicitVisibilityAux(const NamedDecl *ND, return getVisibilityOf(VTSD->getSpecializedTemplate()->getTemplatedDecl(), kind); - return None; + return std::nullopt; } // Also handle function template specializations. if (const auto *fn = dyn_cast<FunctionDecl>(ND)) { @@ -1227,17 +1246,17 @@ getExplicitVisibilityAux(const NamedDecl *ND, if (InstantiatedFrom) return getVisibilityOf(InstantiatedFrom, kind); - return None; + return std::nullopt; } // The visibility of a template is stored in the templated decl. if (const auto *TD = dyn_cast<TemplateDecl>(ND)) return getVisibilityOf(TD->getTemplatedDecl(), kind); - return None; + return std::nullopt; } -Optional<Visibility> +std::optional<Visibility> NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const { return getExplicitVisibilityAux(this, kind, false); } @@ -1252,8 +1271,13 @@ LinkageInfo LinkageComputer::getLVForClosure(const DeclContext *DC, else if (isa<ParmVarDecl>(ContextDecl)) Owner = dyn_cast<NamedDecl>(ContextDecl->getDeclContext()->getRedeclContext()); - else + else if (isa<ImplicitConceptSpecializationDecl>(ContextDecl)) { + // Replace with the concept's owning decl, which is either a namespace or a + // TU, so this needs a dyn_cast. + Owner = dyn_cast<NamedDecl>(ContextDecl->getDeclContext()); + } else { Owner = cast<NamedDecl>(ContextDecl); + } if (!Owner) return LinkageInfo::none(); @@ -1289,7 +1313,7 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D, LinkageInfo LV; if (!hasExplicitVisibilityAlready(computation)) { - if (Optional<Visibility> Vis = + if (std::optional<Visibility> Vis = getExplicitVisibility(Function, computation)) LV.mergeVisibility(*Vis, true); } @@ -1310,7 +1334,8 @@ LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D, if (Var->getStorageClass() == SC_PrivateExtern) LV.mergeVisibility(HiddenVisibility, true); else if (!hasExplicitVisibilityAlready(computation)) { - if (Optional<Visibility> Vis = getExplicitVisibility(Var, computation)) + if (std::optional<Visibility> Vis = + getExplicitVisibility(Var, computation)) LV.mergeVisibility(*Vis, true); } @@ -1505,7 +1530,7 @@ LinkageInfo LinkageComputer::getLVForDecl(const NamedDecl *D, if (computation.IgnoreAllVisibility && D->hasCachedLinkage()) return LinkageInfo(D->getCachedLinkage(), DefaultVisibility, false); - if (llvm::Optional<LinkageInfo> LI = lookup(D, computation)) + if (std::optional<LinkageInfo> LI = lookup(D, computation)) return *LI; LinkageInfo LV = computeLVForDecl(D, computation); @@ -1527,7 +1552,7 @@ LinkageInfo LinkageComputer::getLVForDecl(const NamedDecl *D, // that all other computed linkages match, check that the one we just // computed also does. NamedDecl *Old = nullptr; - for (auto I : D->redecls()) { + for (auto *I : D->redecls()) { auto *T = cast<NamedDecl>(I); if (T == D) continue; @@ -1601,8 +1626,12 @@ Module *Decl::getOwningModuleForLinkage(bool IgnoreLinkage) const { llvm_unreachable("unknown module kind"); } -void NamedDecl::printName(raw_ostream &os) const { - os << Name; +void NamedDecl::printName(raw_ostream &OS, const PrintingPolicy&) const { + OS << Name; +} + +void NamedDecl::printName(raw_ostream &OS) const { + printName(OS, getASTContext().getPrintingPolicy()); } std::string NamedDecl::getQualifiedNameAsString() const { @@ -1620,7 +1649,7 @@ void NamedDecl::printQualifiedName(raw_ostream &OS, const PrintingPolicy &P) const { if (getDeclContext()->isFunctionOrMethod()) { // We do not print '(anonymous)' for function parameters without name. - printName(OS); + printName(OS, P); return; } printNestedNameSpecifier(OS, P); @@ -1631,7 +1660,7 @@ void NamedDecl::printQualifiedName(raw_ostream &OS, // fall back to "(anonymous)". SmallString<64> NameBuffer; llvm::raw_svector_ostream NameOS(NameBuffer); - printName(NameOS); + printName(NameOS, P); if (NameBuffer.empty()) OS << "(anonymous)"; else @@ -1754,7 +1783,7 @@ void NamedDecl::getNameForDiagnostic(raw_ostream &OS, if (Qualified) printQualifiedName(OS, Policy); else - printName(OS); + printName(OS, Policy); } template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) { @@ -1825,7 +1854,7 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const { // Check whether this is actually newer than OldD. We want to keep the // newer declaration. This loop will usually only iterate once, because // OldD is usually the previous declaration. - for (auto D : redecls()) { + for (auto *D : redecls()) { if (D == OldD) break; @@ -2273,7 +2302,7 @@ VarDecl *VarDecl::getActingDefinition() { VarDecl *VarDecl::getDefinition(ASTContext &C) { VarDecl *First = getFirstDecl(); - for (auto I : First->redecls()) { + for (auto *I : First->redecls()) { if (I->isThisDeclarationADefinition(C) == Definition) return I; } @@ -2284,7 +2313,7 @@ VarDecl::DefinitionKind VarDecl::hasDefinition(ASTContext &C) const { DefinitionKind Kind = DeclarationOnly; const VarDecl *First = getFirstDecl(); - for (auto I : First->redecls()) { + for (auto *I : First->redecls()) { Kind = std::max(Kind, I->isThisDeclarationADefinition(C)); if (Kind == Definition) break; @@ -2294,7 +2323,7 @@ VarDecl::DefinitionKind VarDecl::hasDefinition(ASTContext &C) const { } const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const { - for (auto I : redecls()) { + for (auto *I : redecls()) { if (auto Expr = I->getInit()) { D = I; return Expr; @@ -2330,7 +2359,7 @@ Stmt **VarDecl::getInitAddress() { VarDecl *VarDecl::getInitializingDeclaration() { VarDecl *Def = nullptr; - for (auto I : redecls()) { + for (auto *I : redecls()) { if (I->hasInit()) return I; @@ -2580,7 +2609,7 @@ bool VarDecl::isNonEscapingByref() const { bool VarDecl::hasDependentAlignment() const { QualType T = getType(); - return T->isDependentType() || T->isUndeducedAutoType() || + return T->isDependentType() || T->isUndeducedType() || llvm::any_of(specific_attrs<AlignedAttr>(), [](const AlignedAttr *AA) { return AA->isAlignmentDependent(); }); @@ -2870,8 +2899,7 @@ Expr *ParmVarDecl::getDefaultArg() { Expr *Arg = getInit(); if (auto *E = dyn_cast_or_null<FullExpr>(Arg)) - if (!isa<ConstantExpr>(E)) - return E->getSubExpr(); + return E->getSubExpr(); return Arg; } @@ -2970,6 +2998,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, FunctionDeclBits.IsMultiVersion = false; FunctionDeclBits.IsCopyDeductionCandidate = false; FunctionDeclBits.HasODRHash = false; + FunctionDeclBits.FriendConstraintRefersToEnclosingTemplate = false; if (TrailingRequiresClause) setTrailingRequiresClause(TrailingRequiresClause); } @@ -3015,7 +3044,7 @@ FunctionDecl::getDefaultedFunctionInfo() const { } bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const { - for (auto I : redecls()) { + for (auto *I : redecls()) { if (I->doesThisDeclarationHaveABody()) { Definition = I; return true; @@ -3162,11 +3191,13 @@ bool FunctionDecl::isMSVCRTEntryPoint() const { } bool FunctionDecl::isReservedGlobalPlacementOperator() const { - assert(getDeclName().getNameKind() == DeclarationName::CXXOperatorName); - assert(getDeclName().getCXXOverloadedOperator() == OO_New || - getDeclName().getCXXOverloadedOperator() == OO_Delete || - getDeclName().getCXXOverloadedOperator() == OO_Array_New || - getDeclName().getCXXOverloadedOperator() == OO_Array_Delete); + if (getDeclName().getNameKind() != DeclarationName::CXXOperatorName) + return false; + if (getDeclName().getCXXOverloadedOperator() != OO_New && + getDeclName().getCXXOverloadedOperator() != OO_Delete && + getDeclName().getCXXOverloadedOperator() != OO_Array_New && + getDeclName().getCXXOverloadedOperator() != OO_Array_Delete) + return false; if (!getDeclContext()->getRedeclContext()->isTranslationUnit()) return false; @@ -3185,7 +3216,7 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const { } bool FunctionDecl::isReplaceableGlobalAllocationFunction( - Optional<unsigned> *AlignmentParam, bool *IsNothrow) const { + std::optional<unsigned> *AlignmentParam, bool *IsNothrow) const { if (getDeclName().getNameKind() != DeclarationName::CXXOperatorName) return false; if (getDeclName().getCXXOverloadedOperator() != OO_New && @@ -3329,6 +3360,8 @@ bool FunctionDecl::isNoReturn() const { MultiVersionKind FunctionDecl::getMultiVersionKind() const { if (hasAttr<TargetAttr>()) return MultiVersionKind::Target; + if (hasAttr<TargetVersionAttr>()) + return MultiVersionKind::TargetVersion; if (hasAttr<CPUDispatchAttr>()) return MultiVersionKind::CPUDispatch; if (hasAttr<CPUSpecificAttr>()) @@ -3347,7 +3380,8 @@ bool FunctionDecl::isCPUSpecificMultiVersion() const { } bool FunctionDecl::isTargetMultiVersion() const { - return isMultiVersion() && hasAttr<TargetAttr>(); + return isMultiVersion() && + (hasAttr<TargetAttr>() || hasAttr<TargetVersionAttr>()); } bool FunctionDecl::isTargetClonesMultiVersion() const { @@ -3486,8 +3520,8 @@ unsigned FunctionDecl::getMinRequiredArguments() const { bool FunctionDecl::hasOneParamOrDefaultArgs() const { return getNumParams() == 1 || (getNumParams() > 1 && - std::all_of(param_begin() + 1, param_end(), - [](ParmVarDecl *P) { return P->hasDefaultArg(); })); + llvm::all_of(llvm::drop_begin(parameters()), + [](ParmVarDecl *P) { return P->hasDefaultArg(); })); } /// The combination of the extern and inline keywords under MSVC forces @@ -3686,7 +3720,7 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const { // If any declaration is 'inline' but not 'extern', then this definition // is externally visible. - for (auto Redecl : redecls()) { + for (auto *Redecl : redecls()) { if (Redecl->isInlineSpecified() && Redecl->getStorageClass() != SC_Extern) return true; @@ -3703,7 +3737,7 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const { // [...] If all of the file scope declarations for a function in a // translation unit include the inline function specifier without extern, // then the definition in that translation unit is an inline definition. - for (auto Redecl : redecls()) { + for (auto *Redecl : redecls()) { if (RedeclForcesDefC99(Redecl)) return true; } @@ -4408,7 +4442,7 @@ void TagDecl::startDefinition() { if (auto *D = dyn_cast<CXXRecordDecl>(this)) { struct CXXRecordDecl::DefinitionData *Data = new (getASTContext()) struct CXXRecordDecl::DefinitionData(D); - for (auto I : redecls()) + for (auto *I : redecls()) cast<CXXRecordDecl>(I)->DefinitionData = Data; } } @@ -4441,7 +4475,7 @@ TagDecl *TagDecl::getDefinition() const { if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(this)) return CXXRD->getDefinition(); - for (auto R : redecls()) + for (auto *R : redecls()) if (R->isCompleteDefinition()) return R; @@ -4468,6 +4502,23 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) { } } +void TagDecl::printName(raw_ostream &OS, const PrintingPolicy &Policy) const { + DeclarationName Name = getDeclName(); + // If the name is supposed to have an identifier but does not have one, then + // the tag is anonymous and we should print it differently. + if (Name.isIdentifier() && !Name.getAsIdentifierInfo()) { + // If the caller wanted to print a qualified name, they've already printed + // the scope. And if the caller doesn't want that, the scope information + // is already printed as part of the type. + PrintingPolicy Copy(Policy); + Copy.SuppressScope = true; + getASTContext().getTagDeclType(this).print(OS, Copy); + return; + } + // Otherwise, do the normal printing. + Name.print(OS, Policy); +} + void TagDecl::setTemplateParameterListsInfo( ASTContext &Context, ArrayRef<TemplateParameterList *> TPLists) { assert(!TPLists.empty()); @@ -4621,6 +4672,21 @@ SourceRange EnumDecl::getSourceRange() const { return Res; } +void EnumDecl::getValueRange(llvm::APInt &Max, llvm::APInt &Min) const { + unsigned Bitwidth = getASTContext().getIntWidth(getIntegerType()); + unsigned NumNegativeBits = getNumNegativeBits(); + unsigned NumPositiveBits = getNumPositiveBits(); + + if (NumNegativeBits) { + unsigned NumBits = std::max(NumNegativeBits, NumPositiveBits + 1); + Max = llvm::APInt(Bitwidth, 1) << (NumBits - 1); + Min = -Max; + } else { + Max = llvm::APInt(Bitwidth, 1) << NumPositiveBits; + Min = llvm::APInt::getZero(Bitwidth); + } +} + //===----------------------------------------------------------------------===// // RecordDecl Implementation //===----------------------------------------------------------------------===// @@ -4645,6 +4711,7 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C, setParamDestroyedInCallee(false); setArgPassingRestrictions(APK_CanPassInRegs); setIsRandomized(false); + setODRHash(0); } RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC, @@ -4819,6 +4886,19 @@ const FieldDecl *RecordDecl::findFirstNamedDataMember() const { return nullptr; } +unsigned RecordDecl::getODRHash() { + if (hasODRHash()) + return RecordDeclBits.ODRHash; + + // Only calculate hash on first call of getODRHash per record. + ODRHash Hash; + Hash.AddRecordDecl(this); + // For RecordDecl the ODRHash is stored in the remaining 26 + // bit of RecordDeclBits, adjust the hash to accomodate. + setODRHash(Hash.CalculateHash() >> 6); + return RecordDeclBits.ODRHash; +} + //===----------------------------------------------------------------------===// // BlockDecl Implementation //===----------------------------------------------------------------------===// @@ -4968,6 +5048,12 @@ bool ValueDecl::isWeak() const { MostRecent->hasAttr<WeakRefAttr>() || isWeakImported(); } +bool ValueDecl::isInitCapture() const { + if (auto *Var = llvm::dyn_cast<VarDecl>(this)) + return Var->isInitCapture(); + return false; +} + void ImplicitParamDecl::anchor() {} ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC, @@ -5073,8 +5159,9 @@ IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IndirectFieldDecl *IndirectFieldDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - return new (C, ID) IndirectFieldDecl(C, nullptr, SourceLocation(), - DeclarationName(), QualType(), None); + return new (C, ID) + IndirectFieldDecl(C, nullptr, SourceLocation(), DeclarationName(), + QualType(), std::nullopt); } SourceRange EnumConstantDecl::getSourceRange() const { @@ -5179,6 +5266,29 @@ FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C, SourceLocation()); } +void TopLevelStmtDecl::anchor() {} + +TopLevelStmtDecl *TopLevelStmtDecl::Create(ASTContext &C, Stmt *Statement) { + assert(Statement); + assert(C.getLangOpts().IncrementalExtensions && + "Must be used only in incremental mode"); + + SourceLocation BeginLoc = Statement->getBeginLoc(); + DeclContext *DC = C.getTranslationUnitDecl(); + + return new (C, DC) TopLevelStmtDecl(DC, BeginLoc, Statement); +} + +TopLevelStmtDecl *TopLevelStmtDecl::CreateDeserialized(ASTContext &C, + unsigned ID) { + return new (C, ID) + TopLevelStmtDecl(/*DC=*/nullptr, SourceLocation(), /*S=*/nullptr); +} + +SourceRange TopLevelStmtDecl::getSourceRange() const { + return SourceRange(getLocation(), Statement->getEndLoc()); +} + void EmptyDecl::anchor() {} EmptyDecl *EmptyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { @@ -5189,6 +5299,40 @@ EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, unsigned ID) { return new (C, ID) EmptyDecl(nullptr, SourceLocation()); } +HLSLBufferDecl::HLSLBufferDecl(DeclContext *DC, bool CBuffer, + SourceLocation KwLoc, IdentifierInfo *ID, + SourceLocation IDLoc, SourceLocation LBrace) + : NamedDecl(Decl::Kind::HLSLBuffer, DC, IDLoc, DeclarationName(ID)), + DeclContext(Decl::Kind::HLSLBuffer), LBraceLoc(LBrace), KwLoc(KwLoc), + IsCBuffer(CBuffer) {} + +HLSLBufferDecl *HLSLBufferDecl::Create(ASTContext &C, + DeclContext *LexicalParent, bool CBuffer, + SourceLocation KwLoc, IdentifierInfo *ID, + SourceLocation IDLoc, + SourceLocation LBrace) { + // For hlsl like this + // cbuffer A { + // cbuffer B { + // } + // } + // compiler should treat it as + // cbuffer A { + // } + // cbuffer B { + // } + // FIXME: support nested buffers if required for back-compat. + DeclContext *DC = LexicalParent; + HLSLBufferDecl *Result = + new (C, DC) HLSLBufferDecl(DC, CBuffer, KwLoc, ID, IDLoc, LBrace); + return Result; +} + +HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, unsigned ID) { + return new (C, ID) HLSLBufferDecl(nullptr, false, SourceLocation(), nullptr, + SourceLocation(), SourceLocation()); +} + //===----------------------------------------------------------------------===// // ImportDecl Implementation //===----------------------------------------------------------------------===// @@ -5248,11 +5392,11 @@ ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, unsigned ID, ArrayRef<SourceLocation> ImportDecl::getIdentifierLocs() const { if (!isImportComplete()) - return None; + return std::nullopt; const auto *StoredLocs = getTrailingObjects<SourceLocation>(); - return llvm::makeArrayRef(StoredLocs, - getNumModuleIdentifiers(getImportedModule())); + return llvm::ArrayRef(StoredLocs, + getNumModuleIdentifiers(getImportedModule())); } SourceRange ImportDecl::getSourceRange() const { |