diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2012-06-19 13:49:26 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2012-06-19 13:49:26 +0000 |
commit | ed35fd1c6db1680b4526ba64c94e5da6ec203be7 (patch) | |
tree | 18ac8c2240de3141ff98114ea78325435b42ab93 /lib/Sema/SemaDeclAttr.cpp | |
parent | c20c4e79ae1957ec5a88d7653a0aeda24b67ae3a (diff) |
Improves parsing and semantic analysis for MS __declspec attributes. This includes support for the align (which fixes PR12631).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158717 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclAttr.cpp')
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 62 |
1 files changed, 33 insertions, 29 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 94a6f74a32..fb36c9e9ec 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -2894,30 +2894,34 @@ static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; return; } - + //FIXME: The C++0x version of this attribute has more limited applicabilty // than GNU's, and should error out when it is used to specify a // weaker alignment, rather than being silently ignored. if (Attr.getNumArgs() == 0) { - D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, true, 0)); + D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, + true, 0, Attr.isDeclspecAttribute())); return; } - S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0)); + S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0), + Attr.isDeclspecAttribute()); } -void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) { +void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, + bool isDeclSpec) { // FIXME: Handle pack-expansions here. if (DiagnoseUnexpandedParameterPack(E)) return; if (E->isTypeDependent() || E->isValueDependent()) { // Save dependent expressions in the AST to be instantiated. - D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E)); + D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E, + isDeclSpec)); return; } - + SourceLocation AttrLoc = AttrRange.getBegin(); // FIXME: Cache the number on the Attr object? llvm::APSInt Alignment(32); @@ -2932,14 +2936,26 @@ void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) { << E->getSourceRange(); return; } + if (isDeclSpec) { + // We've already verified it's a power of 2, now let's make sure it's + // 8192 or less. + if (Alignment.getZExtValue() > 8192) { + Diag(AttrLoc, diag::err_attribute_aligned_greater_than_8192) + << E->getSourceRange(); + return; + } + } - D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take())); + D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take(), + isDeclSpec)); } -void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS) { +void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS, + bool isDeclSpec) { // FIXME: Cache the number on the Attr object if non-dependent? // FIXME: Perform checking of type validity - D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS)); + D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS, + isDeclSpec)); return; } @@ -3776,22 +3792,6 @@ static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D, ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context)); } -static bool isKnownDeclSpecAttr(const AttributeList &Attr) { - switch (Attr.getKind()) { - default: - return false; - case AttributeList::AT_DLLImport: - case AttributeList::AT_DLLExport: - case AttributeList::AT_Uuid: - case AttributeList::AT_Deprecated: - case AttributeList::AT_NoReturn: - case AttributeList::AT_NoThrow: - case AttributeList::AT_Naked: - case AttributeList::AT_NoInline: - return true; - } -} - //===----------------------------------------------------------------------===// // Microsoft specific attribute handlers. //===----------------------------------------------------------------------===// @@ -4150,8 +4150,9 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, // Ask target about the attribute. const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema(); if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S)) - S.Diag(Attr.getLoc(), diag::warn_unknown_attribute_ignored) - << Attr.getName(); + S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute() ? + diag::warn_unhandled_ms_attribute_ignored : + diag::warn_unknown_attribute_ignored) << Attr.getName(); break; } } @@ -4166,8 +4167,11 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, if (Attr.isInvalid()) return; - if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) - // FIXME: Try to deal with other __declspec attributes! + // Type attributes are still treated as declaration attributes by + // ParseMicrosoftTypeAttributes and ParseBorlandTypeAttributes. We don't + // want to process them, however, because we will simply warn about ignoring + // them. So instead, we will bail out early. + if (Attr.isMSTypespecAttribute()) return; if (NonInheritable) |