21 #include "llvm/ADT/StringExtras.h"
23 using namespace clang;
28 if (!isa<NullStmt>(St)) {
31 if (isa<SwitchCase>(St)) {
33 S.
Diag(L, diag::note_fallthrough_insert_semi_fixit)
53 bool PragmaUnroll = PragmaNameLoc->
Ident->
getName() ==
"unroll";
54 bool PragmaNoUnroll = PragmaNameLoc->
Ident->
getName() ==
"nounroll";
55 if (St->getStmtClass() != Stmt::DoStmtClass &&
56 St->getStmtClass() != Stmt::ForStmtClass &&
57 St->getStmtClass() != Stmt::CXXForRangeStmtClass &&
58 St->getStmtClass() != Stmt::WhileStmtClass) {
60 llvm::StringSwitch<const char *>(PragmaNameLoc->
Ident->
getName())
61 .Case(
"unroll",
"#pragma unroll")
62 .Case(
"nounroll",
"#pragma nounroll")
63 .Default(
"#pragma clang loop");
64 S.
Diag(St->getLocStart(), diag::err_pragma_loop_precedes_nonloop) << Pragma;
68 LoopHintAttr::Spelling Spelling;
69 LoopHintAttr::OptionType Option;
70 LoopHintAttr::LoopHintState
State;
73 Spelling = LoopHintAttr::Pragma_nounroll;
74 Option = LoopHintAttr::Unroll;
75 State = LoopHintAttr::Disable;
76 }
else if (PragmaUnroll) {
77 Spelling = LoopHintAttr::Pragma_unroll;
80 Option = LoopHintAttr::UnrollCount;
81 State = LoopHintAttr::Numeric;
84 Option = LoopHintAttr::Unroll;
85 State = LoopHintAttr::Enable;
89 Spelling = LoopHintAttr::Pragma_clang_loop;
90 assert(OptionLoc && OptionLoc->
Ident &&
91 "Attribute must have valid option info.");
92 Option = llvm::StringSwitch<LoopHintAttr::OptionType>(
94 .Case(
"vectorize", LoopHintAttr::Vectorize)
95 .Case(
"vectorize_width", LoopHintAttr::VectorizeWidth)
96 .Case(
"interleave", LoopHintAttr::Interleave)
97 .Case(
"interleave_count", LoopHintAttr::InterleaveCount)
98 .Case(
"unroll", LoopHintAttr::Unroll)
99 .Case(
"unroll_count", LoopHintAttr::UnrollCount)
100 .Default(LoopHintAttr::Vectorize);
101 if (Option == LoopHintAttr::VectorizeWidth ||
102 Option == LoopHintAttr::InterleaveCount ||
103 Option == LoopHintAttr::UnrollCount) {
104 assert(ValueExpr &&
"Attribute must have a valid value expression.");
107 State = LoopHintAttr::Numeric;
108 }
else if (Option == LoopHintAttr::Vectorize ||
109 Option == LoopHintAttr::Interleave ||
110 Option == LoopHintAttr::Unroll) {
111 assert(StateLoc && StateLoc->
Ident &&
"Loop hint must have an argument");
113 State = LoopHintAttr::Disable;
114 else if (StateLoc->
Ident->
isStr(
"assume_safety"))
115 State = LoopHintAttr::AssumeSafety;
117 State = LoopHintAttr::Full;
119 State = LoopHintAttr::Enable;
121 llvm_unreachable(
"bad loop hint argument");
123 llvm_unreachable(
"bad loop hint");
126 return LoopHintAttr::CreateImplicit(S.
Context, Spelling, Option, State,
142 const LoopHintAttr *StateAttr;
143 const LoopHintAttr *NumericAttr;
144 } HintAttrs[] = {{
nullptr,
nullptr}, {
nullptr,
nullptr}, {
nullptr,
nullptr}};
146 for (
const auto *
I : Attrs) {
147 const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(
I);
153 LoopHintAttr::OptionType Option = LH->getOption();
154 enum { Vectorize, Interleave, Unroll }
Category;
156 case LoopHintAttr::Vectorize:
157 case LoopHintAttr::VectorizeWidth:
160 case LoopHintAttr::Interleave:
161 case LoopHintAttr::InterleaveCount:
164 case LoopHintAttr::Unroll:
165 case LoopHintAttr::UnrollCount:
170 auto &CategoryState = HintAttrs[
Category];
171 const LoopHintAttr *PrevAttr;
172 if (Option == LoopHintAttr::Vectorize ||
173 Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll) {
175 PrevAttr = CategoryState.StateAttr;
176 CategoryState.StateAttr = LH;
179 PrevAttr = CategoryState.NumericAttr;
180 CategoryState.NumericAttr = LH;
187 S.
Diag(OptionLoc, diag::err_pragma_loop_compatibility)
188 <<
true << PrevAttr->getDiagnosticName(Policy)
189 << LH->getDiagnosticName(Policy);
191 if (CategoryState.StateAttr && CategoryState.NumericAttr &&
193 CategoryState.StateAttr->getState() == LoopHintAttr::Disable)) {
198 S.
Diag(OptionLoc, diag::err_pragma_loop_compatibility)
200 << CategoryState.StateAttr->getDiagnosticName(Policy)
201 << CategoryState.NumericAttr->getDiagnosticName(Policy);
211 diag::warn_unhandled_ms_attribute_ignored :
212 diag::warn_unknown_attribute_ignored) << A.
getName();
214 case AttributeList::AT_FallThrough:
216 case AttributeList::AT_LoopHint:
222 << A.
getName() << St->getLocStart();
240 return ActOnAttributedStmt(Range.
getBegin(), Attrs,
S);
Defines the clang::ASTContext interface.
SourceLocation getEnd() const
bool CheckLoopHintExpr(Expr *E, SourceLocation Loc)
Defines the SourceManager interface.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
SourceRange getRange() const
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
SmallVector< SwitchStmt *, 8 > SwitchStack
SwitchStack - This is the current set of active switch statements in the block.
Describes how types, statements, expressions, and declarations should be printed. ...
const LangOptions & getLangOpts() const
detail::InMemoryDirectory::const_iterator I
Sema - This implements semantic analysis and AST building for C.
Expr - This represents one expression.
StringRef getName() const
Return the actual identifier string.
static Attr * handleFallThroughAttr(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range)
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
Wraps an identifier and optional source location for the identifier.
StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs, SourceRange Range)
Stmt attributes - this routine is the top level dispatcher.
unsigned getAttributeSpellingListIndex() const
Get an index into the attribute spelling list defined in Attr.td.
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Encodes a location in the source.
static void CheckForIncompatibleAttributes(Sema &S, const SmallVectorImpl< const Attr * > &Attrs)
static Attr * ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range)
SourceLocation getBegin() const
IdentifierLoc * getArgAsIdent(unsigned Arg) const
sema::FunctionScopeInfo * getCurFunction() const
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
Expr * getArgAsExpr(unsigned Arg) const
IdentifierInfo * getName() const
SourceLocation getLoc() const
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
bool isDeclspecAttribute() const
static Attr * handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A, SourceRange)
AttributeList * getNext() const
A trivial tuple used to represent a source range.
Attr - This represents one attribute.
AttributeList - Represents a syntactic attribute.