diff options
author | Abramo Bagnara <abramo.bagnara@gmail.com> | 2010-04-30 13:10:51 +0000 |
---|---|---|
committer | Abramo Bagnara <abramo.bagnara@gmail.com> | 2010-04-30 13:10:51 +0000 |
commit | e215f7232dd4aa65ebf2a1ecd07cd95fe1ce3481 (patch) | |
tree | 57b9fc35147d28afd5de78f2ac67ac1d65b42e57 /lib/Sema/SemaDeclAttr.cpp | |
parent | b1f1b267351be74013f966f4834cde1eddbe0233 (diff) |
Add calling convention related attributes to related declaration. Mark attributes invalid on type related checking so to add them to declarations only when everything is ok.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102710 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclAttr.cpp')
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 52d9f58d37..90aa9c1c13 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -467,11 +467,10 @@ static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) { } static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, - Sema &S, bool EmitDiagnostics) { + Sema &S) { // check the attribute arguments. if (Attr.getNumArgs() != 0) { - if (EmitDiagnostics) - S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; return false; } @@ -479,11 +478,10 @@ static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, ValueDecl *VD = dyn_cast<ValueDecl>(d); if (VD == 0 || (!VD->getType()->isBlockPointerType() && !VD->getType()->isFunctionPointerType())) { - if (EmitDiagnostics) - S.Diag(Attr.getLoc(), - Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type - : diag::warn_attribute_wrong_decl_type) - << Attr.getName() << 0 /*function*/; + S.Diag(Attr.getLoc(), + Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type + : diag::warn_attribute_wrong_decl_type) + << Attr.getName() << 0 /*function*/; return false; } } @@ -492,17 +490,14 @@ static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, } static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { - /* - Do check for well-formedness, but do not emit diagnostics: - it was already emitted by Sema::ProcessFnAttr(). - */ - if (HandleCommonNoReturnAttr(d, Attr, S, /*EmitDiagnostic=*/false)) - d->addAttr(::new (S.Context) NoReturnAttr()); + /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */ + assert(Attr.isInvalid() == false); + d->addAttr(::new (S.Context) NoReturnAttr()); } static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) { - if (HandleCommonNoReturnAttr(d, Attr, S, true)) + if (HandleCommonNoReturnAttr(d, Attr, S)) d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); } @@ -1647,6 +1642,27 @@ static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { d->addAttr(::new (S.Context) GNUInlineAttr()); } +static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) { + // Diagnostic is emitted elsewhere: here we store the (valid) Attr + // in the Decl node for syntactic reasoning, e.g., pretty-printing. + assert(Attr.isInvalid() == false); + + switch (Attr.getKind()) { + case AttributeList::AT_fastcall: + d->addAttr(::new (S.Context) FastCallAttr()); + return; + case AttributeList::AT_stdcall: + d->addAttr(::new (S.Context) StdCallAttr()); + return; + case AttributeList::AT_cdecl: + d->addAttr(::new (S.Context) CDeclAttr()); + return; + default: + llvm_unreachable("unexpected attribute kind"); + return; + } +} + static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { // check the attribute arguments. if (Attr.getNumArgs() != 1) { @@ -1847,6 +1863,9 @@ static bool isKnownDeclSpecAttr(const AttributeList &Attr) { /// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). static void ProcessDeclAttribute(Scope *scope, Decl *D, const AttributeList &Attr, Sema &S) { + if (Attr.isInvalid()) + return; + if (Attr.isDeclspecAttribute() && !isKnownDeclSpecAttr(Attr)) // FIXME: Try to deal with other __declspec attributes! return; @@ -1931,7 +1950,7 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D, case AttributeList::AT_stdcall: case AttributeList::AT_cdecl: case AttributeList::AT_fastcall: - // These are all treated as type attributes. + HandleCallConvAttr(D, Attr, S); break; default: // Ask target about the attribute. |