diff options
author | Joel E. Denny <dennyje@ornl.gov> | 2018-03-02 19:03:22 +0000 |
---|---|---|
committer | Joel E. Denny <dennyje@ornl.gov> | 2018-03-02 19:03:22 +0000 |
commit | 492544595874cef5b7ccd37be54c98cd37f8a1ea (patch) | |
tree | 1fd34fa1e3ade78c8f8a520e9c7169de3fdda6ab /clang/lib/Sema | |
parent | 1a8456da17075539099ccb0d625fda816b62bcb2 (diff) | |
download | bcm5719-llvm-492544595874cef5b7ccd37be54c98cd37f8a1ea.tar.gz bcm5719-llvm-492544595874cef5b7ccd37be54c98cd37f8a1ea.zip |
[Attr] Fix parameter indexing for several attributes
The patch fixes a number of bugs related to parameter indexing in
attributes:
* Parameter indices in some attributes (argument_with_type_tag,
pointer_with_type_tag, nonnull, ownership_takes, ownership_holds,
and ownership_returns) are specified in source as one-origin
including any C++ implicit this parameter, were stored as
zero-origin excluding any this parameter, and were erroneously
printing (-ast-print) and confusingly dumping (-ast-dump) as the
stored values.
* For alloc_size, the C++ implicit this parameter was not subtracted
correctly in Sema, leading to assert failures or to silent failures
of __builtin_object_size to compute a value.
* For argument_with_type_tag, pointer_with_type_tag, and
ownership_returns, the C++ implicit this parameter was not added
back to parameter indices in some diagnostics.
This patch fixes the above bugs and aims to prevent similar bugs in
the future by introducing careful mechanisms for handling parameter
indices in attributes. ParamIdx stores a parameter index and is
designed to hide the stored encoding while providing accessors that
require each use (such as printing) to make explicit the encoding that
is needed. Attribute declarations declare parameter index arguments
as [Variadic]ParamIdxArgument, which are exposed as ParamIdx[*]. This
patch rewrites all attribute arguments that are processed by
checkFunctionOrMethodParameterIndex in SemaDeclAttr.cpp to be declared
as [Variadic]ParamIdxArgument. The only exception is xray_log_args's
argument, which is encoded as a count not an index.
Differential Revision: https://reviews.llvm.org/D43248
llvm-svn: 326602
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 37 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 149 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 |
4 files changed, 84 insertions, 106 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 568ba98020e..9caabde35b6 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2619,12 +2619,13 @@ static void CheckNonNullArguments(Sema &S, return; } - for (unsigned Val : NonNull->args()) { - if (Val >= Args.size()) + for (const ParamIdx &Idx : NonNull->args()) { + unsigned IdxAST = Idx.getASTIndex(); + if (IdxAST >= Args.size()) continue; if (NonNullArgs.empty()) NonNullArgs.resize(Args.size()); - NonNullArgs.set(Val); + NonNullArgs.set(IdxAST); } } } @@ -5002,12 +5003,7 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args, const CallExpr *CE = cast<CallExpr>(E); if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl())) { if (const FormatArgAttr *FA = ND->getAttr<FormatArgAttr>()) { - unsigned ArgIndex = FA->getFormatIdx(); - if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ND)) - if (MD->isInstance()) - --ArgIndex; - const Expr *Arg = CE->getArg(ArgIndex - 1); - + const Expr *Arg = CE->getArg(FA->formatIdx().getASTIndex()); return checkFormatStringExpr(S, Arg, Args, HasVAListArg, format_idx, firstDataArg, Type, CallType, InFunctionCall, @@ -5032,8 +5028,7 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args, const auto *ME = cast<ObjCMessageExpr>(E); if (const auto *ND = ME->getMethodDecl()) { if (const auto *FA = ND->getAttr<FormatArgAttr>()) { - unsigned ArgIndex = FA->getFormatIdx(); - const Expr *Arg = ME->getArg(ArgIndex - 1); + const Expr *Arg = ME->getArg(FA->formatIdx().getASTIndex()); return checkFormatStringExpr( S, Arg, Args, HasVAListArg, format_idx, firstDataArg, Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset); @@ -10086,8 +10081,8 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E, return; } - for (unsigned ArgNo : NonNull->args()) { - if (ArgNo == ParamNo) { + for (const ParamIdx &ArgNo : NonNull->args()) { + if (ArgNo.getASTIndex() == ParamNo) { ComplainAboutNonnullParamOrCall(NonNull); return; } @@ -12242,13 +12237,13 @@ void Sema::CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr, bool IsPointerAttr = Attr->getIsPointer(); // Retrieve the argument representing the 'type_tag'. - if (Attr->getTypeTagIdx() >= ExprArgs.size()) { - // Add 1 to display the user's specified value. + unsigned TypeTagIdxAST = Attr->typeTagIdx().getASTIndex(); + if (TypeTagIdxAST >= ExprArgs.size()) { Diag(CallSiteLoc, diag::err_tag_index_out_of_range) - << 0 << Attr->getTypeTagIdx() + 1; + << 0 << Attr->typeTagIdx().getSourceIndex(); return; } - const Expr *TypeTagExpr = ExprArgs[Attr->getTypeTagIdx()]; + const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST]; bool FoundWrongKind; TypeTagData TypeInfo; if (!GetMatchingCType(ArgumentKind, TypeTagExpr, Context, @@ -12262,13 +12257,13 @@ void Sema::CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr, } // Retrieve the argument representing the 'arg_idx'. - if (Attr->getArgumentIdx() >= ExprArgs.size()) { - // Add 1 to display the user's specified value. + unsigned ArgumentIdxAST = Attr->argumentIdx().getASTIndex(); + if (ArgumentIdxAST >= ExprArgs.size()) { Diag(CallSiteLoc, diag::err_tag_index_out_of_range) - << 1 << Attr->getArgumentIdx() + 1; + << 1 << Attr->argumentIdx().getSourceIndex(); return; } - const Expr *ArgumentExpr = ExprArgs[Attr->getArgumentIdx()]; + const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST]; if (IsPointerAttr) { // Skip implicit cast of pointer to `void *' (as a function argument). if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr)) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index b358b04142f..bf54824e4ef 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -13176,7 +13176,7 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { // We already have a __builtin___CFStringMakeConstantString, // but builds that use -fno-constant-cfstrings don't go through that. if (!FD->hasAttr<FormatArgAttr>()) - FD->addAttr(FormatArgAttr::CreateImplicit(Context, 1, + FD->addAttr(FormatArgAttr::CreateImplicit(Context, ParamIdx(1, FD), FD->getLocation())); } } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index fe05692f0a5..fee61e19d5d 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -311,7 +311,7 @@ static bool checkAttrMutualExclusion(Sema &S, Decl *D, SourceRange Range, template <typename AttrInfo> static bool checkFunctionOrMethodParameterIndex( Sema &S, const Decl *D, const AttrInfo &AI, unsigned AttrArgNum, - const Expr *IdxExpr, uint64_t &Idx, bool AllowImplicitThis = false) { + const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis = false) { assert(isFunctionOrMethodOrBlock(D)); // In C++ the implicit 'this' function parameter also counts. @@ -331,21 +331,20 @@ static bool checkFunctionOrMethodParameterIndex( return false; } - Idx = IdxInt.getLimitedValue(); - if (Idx < 1 || (!IV && Idx > NumParams)) { + Idx = ParamIdx(IdxInt.getLimitedValue(UINT_MAX), D); + unsigned IdxSource = Idx.getSourceIndex(); + if (IdxSource < 1 || (!IV && IdxSource > NumParams)) { S.Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds) - << getAttrName(AI) << AttrArgNum << IdxExpr->getSourceRange(); + << getAttrName(AI) << AttrArgNum << IdxExpr->getSourceRange(); return false; } - Idx--; // Convert to zero-based. - if (HasImplicitThisParam && !AllowImplicitThis) { - if (Idx == 0) { + if (HasImplicitThisParam && !CanIndexImplicitThis) { + if (IdxSource == 1) { S.Diag(getAttrLoc(AI), diag::err_attribute_invalid_implicit_this_argument) - << getAttrName(AI) << IdxExpr->getSourceRange(); + << getAttrName(AI) << IdxExpr->getSourceRange(); return false; } - --Idx; } return true; @@ -772,18 +771,15 @@ static void handleAssertExclusiveLockAttr(Sema &S, Decl *D, /// AttrArgNo is used to actually retrieve the argument, so it's base-0. template <typename AttrInfo> static bool checkParamIsIntegerType(Sema &S, const FunctionDecl *FD, - const AttrInfo &AI, unsigned AttrArgNo, - bool AllowDependentType = false) { + const AttrInfo &AI, unsigned AttrArgNo) { assert(AI.isArgExpr(AttrArgNo) && "Expected expression argument"); Expr *AttrArg = AI.getArgAsExpr(AttrArgNo); - uint64_t Idx; + ParamIdx Idx; if (!checkFunctionOrMethodParameterIndex(S, FD, AI, AttrArgNo + 1, AttrArg, Idx)) return false; - const ParmVarDecl *Param = FD->getParamDecl(Idx); - if (AllowDependentType && Param->getType()->isDependentType()) - return true; + const ParmVarDecl *Param = FD->getParamDecl(Idx.getASTIndex()); if (!Param->getType()->isIntegerType() && !Param->getType()->isCharType()) { SourceLocation SrcLoc = AttrArg->getLocStart(); S.Diag(SrcLoc, diag::err_attribute_integers_only) @@ -806,22 +802,23 @@ static void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &AL) { } const Expr *SizeExpr = AL.getArgAsExpr(0); - int SizeArgNo; + int SizeArgNoVal; // Parameter indices are 1-indexed, hence Index=1 - if (!checkPositiveIntArgument(S, AL, SizeExpr, SizeArgNo, /*Index=*/1)) + if (!checkPositiveIntArgument(S, AL, SizeExpr, SizeArgNoVal, /*Index=*/1)) return; + ParamIdx SizeArgNo(SizeArgNoVal, D); if (!checkParamIsIntegerType(S, FD, AL, /*AttrArgNo=*/0)) return; - // Args are 1-indexed, so 0 implies that the arg was not present - int NumberArgNo = 0; + ParamIdx NumberArgNo; if (AL.getNumArgs() == 2) { const Expr *NumberExpr = AL.getArgAsExpr(1); + int Val; // Parameter indices are 1-based, hence Index=2 - if (!checkPositiveIntArgument(S, AL, NumberExpr, NumberArgNo, - /*Index=*/2)) + if (!checkPositiveIntArgument(S, AL, NumberExpr, Val, /*Index=*/2)) return; + NumberArgNo = ParamIdx(Val, D); if (!checkParamIsIntegerType(S, FD, AL, /*AttrArgNo=*/1)) return; @@ -1424,18 +1421,19 @@ static bool attrNonNullArgCheck(Sema &S, QualType T, const AttributeList &AL, } static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &AL) { - SmallVector<unsigned, 8> NonNullArgs; + SmallVector<ParamIdx, 8> NonNullArgs; for (unsigned I = 0; I < AL.getNumArgs(); ++I) { Expr *Ex = AL.getArgAsExpr(I); - uint64_t Idx; + ParamIdx Idx; if (!checkFunctionOrMethodParameterIndex(S, D, AL, I + 1, Ex, Idx)) return; // Is the function argument a pointer type? - if (Idx < getFunctionOrMethodNumParams(D) && - !attrNonNullArgCheck(S, getFunctionOrMethodParamType(D, Idx), AL, - Ex->getSourceRange(), - getFunctionOrMethodParamRange(D, Idx))) + if (Idx.getASTIndex() < getFunctionOrMethodNumParams(D) && + !attrNonNullArgCheck( + S, getFunctionOrMethodParamType(D, Idx.getASTIndex()), AL, + Ex->getSourceRange(), + getFunctionOrMethodParamRange(D, Idx.getASTIndex()))) continue; NonNullArgs.push_back(Idx); @@ -1459,12 +1457,12 @@ static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &AL) { S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_no_pointers); } - unsigned *Start = NonNullArgs.data(); + ParamIdx *Start = NonNullArgs.data(); unsigned Size = NonNullArgs.size(); llvm::array_pod_sort(Start, Start + Size); D->addAttr(::new (S.Context) - NonNullAttr(AL.getRange(), S.Context, Start, Size, - AL.getAttributeSpellingListIndex())); + NonNullAttr(AL.getRange(), S.Context, Start, Size, + AL.getAttributeSpellingListIndex())); } static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D, @@ -1485,8 +1483,8 @@ static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D, return; D->addAttr(::new (S.Context) - NonNullAttr(AL.getRange(), S.Context, nullptr, 0, - AL.getAttributeSpellingListIndex())); + NonNullAttr(AL.getRange(), S.Context, nullptr, 0, + AL.getAttributeSpellingListIndex())); } static void handleReturnsNonNullAttr(Sema &S, Decl *D, @@ -1587,7 +1585,7 @@ void Sema::AddAllocAlignAttr(SourceRange AttrRange, Decl *D, Expr *ParamExpr, unsigned SpellingListIndex) { QualType ResultType = getFunctionOrMethodResultType(D); - AllocAlignAttr TmpAttr(AttrRange, Context, 0, SpellingListIndex); + AllocAlignAttr TmpAttr(AttrRange, Context, ParamIdx(), SpellingListIndex); SourceLocation AttrLoc = AttrRange.getBegin(); if (!ResultType->isDependentType() && @@ -1597,28 +1595,22 @@ void Sema::AddAllocAlignAttr(SourceRange AttrRange, Decl *D, Expr *ParamExpr, return; } - uint64_t IndexVal; + ParamIdx Idx; const auto *FuncDecl = cast<FunctionDecl>(D); if (!checkFunctionOrMethodParameterIndex(*this, FuncDecl, TmpAttr, - /*AttrArgNo=*/1, ParamExpr, - IndexVal)) + /*AttrArgNo=*/1, ParamExpr, Idx)) return; - QualType Ty = getFunctionOrMethodParamType(D, IndexVal); + QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex()); if (!Ty->isDependentType() && !Ty->isIntegralType(Context)) { Diag(ParamExpr->getLocStart(), diag::err_attribute_integers_only) - << &TmpAttr << FuncDecl->getParamDecl(IndexVal)->getSourceRange(); + << &TmpAttr + << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange(); return; } - // We cannot use the Idx returned from checkFunctionOrMethodParameterIndex - // because that has corrected for the implicit this parameter, and is zero- - // based. The attribute expects what the user wrote explicitly. - llvm::APSInt Val; - ParamExpr->EvaluateAsInt(Val, Context); - - D->addAttr(::new (Context) AllocAlignAttr( - AttrRange, Context, Val.getZExtValue(), SpellingListIndex)); + D->addAttr(::new (Context) + AllocAlignAttr(AttrRange, Context, Idx, SpellingListIndex)); } /// Normalize the attribute, __foo__ becomes foo. @@ -1678,15 +1670,15 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { Module = &S.PP.getIdentifierTable().get(ModuleName); } - SmallVector<unsigned, 8> OwnershipArgs; + SmallVector<ParamIdx, 8> OwnershipArgs; for (unsigned i = 1; i < AL.getNumArgs(); ++i) { Expr *Ex = AL.getArgAsExpr(i); - uint64_t Idx; + ParamIdx Idx; if (!checkFunctionOrMethodParameterIndex(S, D, AL, i, Ex, Idx)) return; // Is the function argument a pointer type? - QualType T = getFunctionOrMethodParamType(D, Idx); + QualType T = getFunctionOrMethodParamType(D, Idx.getASTIndex()); int Err = -1; // No error switch (K) { case OwnershipAttr::Takes: @@ -1717,14 +1709,13 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { } else if (K == OwnershipAttr::Returns && I->getOwnKind() == OwnershipAttr::Returns) { // A returns attribute conflicts with any other returns attribute using - // a different index. Note, diagnostic reporting is 1-based, but stored - // argument indexes are 0-based. + // a different index. if (std::find(I->args_begin(), I->args_end(), Idx) == I->args_end()) { S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch) - << *(I->args_begin()) + 1; + << I->args_begin()->getSourceIndex(); if (I->args_size()) S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch) - << (unsigned)Idx + 1 << Ex->getSourceRange(); + << Idx.getSourceIndex() << Ex->getSourceRange(); return; } } @@ -1732,13 +1723,12 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) { OwnershipArgs.push_back(Idx); } - unsigned* start = OwnershipArgs.data(); - unsigned size = OwnershipArgs.size(); - llvm::array_pod_sort(start, start + size); - + ParamIdx *Start = OwnershipArgs.data(); + unsigned Size = OwnershipArgs.size(); + llvm::array_pod_sort(Start, Start + Size); D->addAttr(::new (S.Context) - OwnershipAttr(AL.getLoc(), S.Context, Module, start, size, - AL.getAttributeSpellingListIndex())); + OwnershipAttr(AL.getLoc(), S.Context, Module, Start, Size, + AL.getAttributeSpellingListIndex())); } static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &AL) { @@ -3109,12 +3099,12 @@ static void handleEnumExtensibilityAttr(Sema &S, Decl *D, /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &AL) { Expr *IdxExpr = AL.getArgAsExpr(0); - uint64_t Idx; + ParamIdx Idx; if (!checkFunctionOrMethodParameterIndex(S, D, AL, 1, IdxExpr, Idx)) return; // Make sure the format string is really a string. - QualType Ty = getFunctionOrMethodParamType(D, Idx); + QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex()); bool NotNSStringTy = !isNSStringType(Ty, S.Context); if (NotNSStringTy && @@ -3137,15 +3127,8 @@ static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &AL) { return; } - // We cannot use the Idx returned from checkFunctionOrMethodParameterIndex - // because that has corrected for the implicit this parameter, and is zero- - // based. The attribute expects what the user wrote explicitly. - llvm::APSInt Val; - IdxExpr->EvaluateAsInt(Val, S.Context); - - D->addAttr(::new (S.Context) - FormatArgAttr(AL.getRange(), S.Context, Val.getZExtValue(), - AL.getAttributeSpellingListIndex())); + D->addAttr(::new (S.Context) FormatArgAttr( + AL.getRange(), S.Context, Idx, AL.getAttributeSpellingListIndex())); } enum FormatAttrKind { @@ -4539,13 +4522,13 @@ static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, << AL.getName() << /* arg num = */ 1 << AANT_ArgumentIdentifier; return; } - - uint64_t ArgumentIdx; + + ParamIdx ArgumentIdx; if (!checkFunctionOrMethodParameterIndex(S, D, AL, 2, AL.getArgAsExpr(1), ArgumentIdx)) return; - uint64_t TypeTagIdx; + ParamIdx TypeTagIdx; if (!checkFunctionOrMethodParameterIndex(S, D, AL, 3, AL.getArgAsExpr(2), TypeTagIdx)) return; @@ -4553,8 +4536,9 @@ static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D, bool IsPointer = AL.getName()->getName() == "pointer_with_type_tag"; if (IsPointer) { // Ensure that buffer has a pointer type. - if (ArgumentIdx >= getFunctionOrMethodNumParams(D) || - !getFunctionOrMethodParamType(D, ArgumentIdx)->isPointerType()) + unsigned ArgumentIdxAST = ArgumentIdx.getASTIndex(); + if (ArgumentIdxAST >= getFunctionOrMethodNumParams(D) || + !getFunctionOrMethodParamType(D, ArgumentIdxAST)->isPointerType()) S.Diag(AL.getLoc(), diag::err_attribute_pointers_only) << AL.getName() << 0; } @@ -4594,19 +4578,18 @@ static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D, AL.getAttributeSpellingListIndex())); } -static void handleXRayLogArgsAttr(Sema &S, Decl *D, - const AttributeList &AL) { - uint64_t ArgCount; +static void handleXRayLogArgsAttr(Sema &S, Decl *D, const AttributeList &AL) { + ParamIdx ArgCount; if (!checkFunctionOrMethodParameterIndex(S, D, AL, 1, AL.getArgAsExpr(0), ArgCount, - true /* AllowImplicitThis*/)) + true /* CanIndexImplicitThis */)) return; - // ArgCount isn't a parameter index [0;n), it's a count [1;n] - hence + 1. - D->addAttr(::new (S.Context) - XRayLogArgsAttr(AL.getRange(), S.Context, ++ArgCount, - AL.getAttributeSpellingListIndex())); + // ArgCount isn't a parameter index [0;n), it's a count [1;n] + D->addAttr(::new (S.Context) XRayLogArgsAttr( + AL.getRange(), S.Context, ArgCount.getSourceIndex(), + AL.getAttributeSpellingListIndex())); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 800956dd535..108724f2a18 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -176,7 +176,7 @@ static void instantiateDependentAllocAlignAttr( Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const AllocAlignAttr *Align, Decl *New) { Expr *Param = IntegerLiteral::Create( - S.getASTContext(), llvm::APInt(64, Align->getParamIndex()), + S.getASTContext(), llvm::APInt(64, Align->paramIndex().getSourceIndex()), S.getASTContext().UnsignedLongLongTy, Align->getLocation()); S.AddAllocAlignAttr(Align->getLocation(), New, Param, Align->getSpellingListIndex()); |