diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 30 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 23 |
3 files changed, 40 insertions, 16 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index e719cd74537..9d5e290b2f6 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -4088,6 +4088,9 @@ public: /// FreePackedContext - Deallocate and null out PackContext. void FreePackedContext(); + /// AddAlignedAttr - Adds an aligned attribute to a particular declaration. + void AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E); + /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit /// cast. If there is already an implicit cast, merge into the existing one. /// If isLvalue, the result of the cast is an lvalue. diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 527b469fed8..0f53fb92ef6 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1458,7 +1458,7 @@ static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString())); } -static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { +static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) { // check the attribute arguments. if (Attr.getNumArgs() > 1) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; @@ -1469,30 +1469,36 @@ static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { // than GNU's, and should error out when it is used to specify a // weaker alignment, rather than being silently ignored. - unsigned Align = 0; if (Attr.getNumArgs() == 0) { // FIXME: This should be the target specific maximum alignment. // (For now we just use 128 bits which is the maximum on X86). - Align = 128; - d->addAttr(::new (S.Context) AlignedAttr(Align)); + D->addAttr(::new (S.Context) AlignedAttr(128)); + return; + } + + S.AddAlignedAttr(Attr.getLoc(), D, static_cast<Expr *>(Attr.getArg(0))); +} + +void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) { + if (E->isTypeDependent() || E->isValueDependent()) { + // Save dependent expressions in the AST to be instantiated. + D->addAttr(::new (Context) AlignedAttr(E)); return; } - Expr *alignmentExpr = static_cast<Expr *>(Attr.getArg(0)); llvm::APSInt Alignment(32); - if (alignmentExpr->isTypeDependent() || alignmentExpr->isValueDependent() || - !alignmentExpr->isIntegerConstantExpr(Alignment, S.Context)) { - S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) - << "aligned" << alignmentExpr->getSourceRange(); + if (!E->isIntegerConstantExpr(Alignment, Context)) { + Diag(AttrLoc, diag::err_attribute_argument_not_int) + << "aligned" << E->getSourceRange(); return; } if (!llvm::isPowerOf2_64(Alignment.getZExtValue())) { - S.Diag(Attr.getLoc(), diag::err_attribute_aligned_not_power_of_two) - << alignmentExpr->getSourceRange(); + Diag(AttrLoc, diag::err_attribute_aligned_not_power_of_two) + << E->getSourceRange(); return; } - d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8)); + D->addAttr(::new (Context) AlignedAttr(Alignment.getZExtValue() * 8)); } /// HandleModeAttr - This attribute modifies the width of a decl with primitive diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 1b28579e61d..06f38e88d58 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -143,14 +143,29 @@ bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl, return false; } -// FIXME: Is this too simple? +// FIXME: Is this still too simple? void TemplateDeclInstantiator::InstantiateAttrs(Decl *Tmpl, Decl *New) { - for (const Attr *TmplAttr = Tmpl->getAttrs(); TmplAttr; + for (const Attr *TmplAttr = Tmpl->getAttrs(); TmplAttr; TmplAttr = TmplAttr->getNext()) { - + // FIXME: This should be generalized to more than just the AlignedAttr. + if (const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr)) { + if (Aligned->isDependent()) { + // The alignment expression is not potentially evaluated. + EnterExpressionEvaluationContext Unevaluated(SemaRef, + Action::Unevaluated); + + OwningExprResult Result = SemaRef.SubstExpr(Aligned->getAlignmentExpr(), + TemplateArgs); + if (!Result.isInvalid()) + // FIXME: Is this the correct source location? + SemaRef.AddAlignedAttr(Aligned->getAlignmentExpr()->getExprLoc(), + New, Result.takeAs<Expr>()); + continue; + } + } + // FIXME: Is cloning correct for all attributes? Attr *NewAttr = TmplAttr->clone(SemaRef.Context); - New->addAttr(NewAttr); } } |

