xref: /minix3/external/bsd/llvm/dist/clang/lib/Sema/SemaStmtAttr.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc //===--- SemaStmtAttr.cpp - Statement Attribute Handling ------------------===//
2*f4a2713aSLionel Sambuc //
3*f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4*f4a2713aSLionel Sambuc //
5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7*f4a2713aSLionel Sambuc //
8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9*f4a2713aSLionel Sambuc //
10*f4a2713aSLionel Sambuc //  This file implements stmt-related attribute processing.
11*f4a2713aSLionel Sambuc //
12*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13*f4a2713aSLionel Sambuc 
14*f4a2713aSLionel Sambuc #include "clang/Sema/SemaInternal.h"
15*f4a2713aSLionel Sambuc #include "TargetAttributesSema.h"
16*f4a2713aSLionel Sambuc #include "clang/AST/ASTContext.h"
17*f4a2713aSLionel Sambuc #include "clang/Basic/SourceManager.h"
18*f4a2713aSLionel Sambuc #include "clang/Lex/Lexer.h"
19*f4a2713aSLionel Sambuc #include "clang/Sema/DelayedDiagnostic.h"
20*f4a2713aSLionel Sambuc #include "clang/Sema/Lookup.h"
21*f4a2713aSLionel Sambuc #include "clang/Sema/ScopeInfo.h"
22*f4a2713aSLionel Sambuc #include "llvm/ADT/StringExtras.h"
23*f4a2713aSLionel Sambuc 
24*f4a2713aSLionel Sambuc using namespace clang;
25*f4a2713aSLionel Sambuc using namespace sema;
26*f4a2713aSLionel Sambuc 
27*f4a2713aSLionel Sambuc static Attr *handleFallThroughAttr(Sema &S, Stmt *St, const AttributeList &A,
28*f4a2713aSLionel Sambuc                                    SourceRange Range) {
29*f4a2713aSLionel Sambuc   if (!isa<NullStmt>(St)) {
30*f4a2713aSLionel Sambuc     S.Diag(A.getRange().getBegin(), diag::err_fallthrough_attr_wrong_target)
31*f4a2713aSLionel Sambuc         << St->getLocStart();
32*f4a2713aSLionel Sambuc     if (isa<SwitchCase>(St)) {
33*f4a2713aSLionel Sambuc       SourceLocation L = Lexer::getLocForEndOfToken(Range.getEnd(), 0,
34*f4a2713aSLionel Sambuc                                   S.getSourceManager(), S.getLangOpts());
35*f4a2713aSLionel Sambuc       S.Diag(L, diag::note_fallthrough_insert_semi_fixit)
36*f4a2713aSLionel Sambuc           << FixItHint::CreateInsertion(L, ";");
37*f4a2713aSLionel Sambuc     }
38*f4a2713aSLionel Sambuc     return 0;
39*f4a2713aSLionel Sambuc   }
40*f4a2713aSLionel Sambuc   if (S.getCurFunction()->SwitchStack.empty()) {
41*f4a2713aSLionel Sambuc     S.Diag(A.getRange().getBegin(), diag::err_fallthrough_attr_outside_switch);
42*f4a2713aSLionel Sambuc     return 0;
43*f4a2713aSLionel Sambuc   }
44*f4a2713aSLionel Sambuc   return ::new (S.Context) FallThroughAttr(A.getRange(), S.Context);
45*f4a2713aSLionel Sambuc }
46*f4a2713aSLionel Sambuc 
47*f4a2713aSLionel Sambuc 
48*f4a2713aSLionel Sambuc static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A,
49*f4a2713aSLionel Sambuc                                   SourceRange Range) {
50*f4a2713aSLionel Sambuc   switch (A.getKind()) {
51*f4a2713aSLionel Sambuc   case AttributeList::UnknownAttribute:
52*f4a2713aSLionel Sambuc     S.Diag(A.getLoc(), A.isDeclspecAttribute() ?
53*f4a2713aSLionel Sambuc            diag::warn_unhandled_ms_attribute_ignored :
54*f4a2713aSLionel Sambuc            diag::warn_unknown_attribute_ignored) << A.getName();
55*f4a2713aSLionel Sambuc     return 0;
56*f4a2713aSLionel Sambuc   case AttributeList::AT_FallThrough:
57*f4a2713aSLionel Sambuc     return handleFallThroughAttr(S, St, A, Range);
58*f4a2713aSLionel Sambuc   default:
59*f4a2713aSLionel Sambuc     // if we're here, then we parsed a known attribute, but didn't recognize
60*f4a2713aSLionel Sambuc     // it as a statement attribute => it is declaration attribute
61*f4a2713aSLionel Sambuc     S.Diag(A.getRange().getBegin(), diag::err_attribute_invalid_on_stmt)
62*f4a2713aSLionel Sambuc         << A.getName() << St->getLocStart();
63*f4a2713aSLionel Sambuc     return 0;
64*f4a2713aSLionel Sambuc   }
65*f4a2713aSLionel Sambuc }
66*f4a2713aSLionel Sambuc 
67*f4a2713aSLionel Sambuc StmtResult Sema::ProcessStmtAttributes(Stmt *S, AttributeList *AttrList,
68*f4a2713aSLionel Sambuc                                        SourceRange Range) {
69*f4a2713aSLionel Sambuc   SmallVector<const Attr*, 8> Attrs;
70*f4a2713aSLionel Sambuc   for (const AttributeList* l = AttrList; l; l = l->getNext()) {
71*f4a2713aSLionel Sambuc     if (Attr *a = ProcessStmtAttribute(*this, S, *l, Range))
72*f4a2713aSLionel Sambuc       Attrs.push_back(a);
73*f4a2713aSLionel Sambuc   }
74*f4a2713aSLionel Sambuc 
75*f4a2713aSLionel Sambuc   if (Attrs.empty())
76*f4a2713aSLionel Sambuc     return S;
77*f4a2713aSLionel Sambuc 
78*f4a2713aSLionel Sambuc   return ActOnAttributedStmt(Range.getBegin(), Attrs, S);
79*f4a2713aSLionel Sambuc }
80