20 #include "llvm/ADT/StringExtras.h" 22 using namespace clang;
29 if (!isa<NullStmt>(St)) {
32 if (isa<SwitchCase>(St)) {
34 S.
Diag(L, diag::note_fallthrough_insert_semi_fixit)
40 if (FnScope->SwitchStack.empty()) {
51 FnScope->setHasFallthroughStmt();
58 S.
Diag(A.
getLoc(), diag::err_attribute_too_few_arguments) << A << 1;
62 std::vector<StringRef> DiagnosticIdentifiers;
63 for (
unsigned I = 0, E = A.
getNumArgs(); I != E; ++I) {
71 DiagnosticIdentifiers.push_back(RuleName);
74 return ::new (S.
Context) SuppressAttr(
86 bool PragmaUnroll = PragmaNameLoc->
Ident->
getName() ==
"unroll";
87 bool PragmaNoUnroll = PragmaNameLoc->
Ident->
getName() ==
"nounroll";
88 bool PragmaUnrollAndJam = PragmaNameLoc->
Ident->
getName() ==
"unroll_and_jam";
89 bool PragmaNoUnrollAndJam =
96 llvm::StringSwitch<const char *>(PragmaNameLoc->
Ident->
getName())
97 .Case(
"unroll",
"#pragma unroll")
98 .Case(
"nounroll",
"#pragma nounroll")
99 .Case(
"unroll_and_jam",
"#pragma unroll_and_jam")
100 .Case(
"nounroll_and_jam",
"#pragma nounroll_and_jam")
101 .Default(
"#pragma clang loop");
102 S.
Diag(St->
getBeginLoc(), diag::err_pragma_loop_precedes_nonloop) << Pragma;
106 LoopHintAttr::Spelling Spelling =
108 LoopHintAttr::OptionType Option;
109 LoopHintAttr::LoopHintState
State;
110 if (PragmaNoUnroll) {
112 Option = LoopHintAttr::Unroll;
113 State = LoopHintAttr::Disable;
114 }
else if (PragmaUnroll) {
117 Option = LoopHintAttr::UnrollCount;
118 State = LoopHintAttr::Numeric;
121 Option = LoopHintAttr::Unroll;
122 State = LoopHintAttr::Enable;
124 }
else if (PragmaNoUnrollAndJam) {
126 Option = LoopHintAttr::UnrollAndJam;
127 State = LoopHintAttr::Disable;
128 }
else if (PragmaUnrollAndJam) {
131 Option = LoopHintAttr::UnrollAndJamCount;
132 State = LoopHintAttr::Numeric;
135 Option = LoopHintAttr::UnrollAndJam;
136 State = LoopHintAttr::Enable;
140 assert(OptionLoc && OptionLoc->
Ident &&
141 "Attribute must have valid option info.");
142 Option = llvm::StringSwitch<LoopHintAttr::OptionType>(
144 .Case(
"vectorize", LoopHintAttr::Vectorize)
145 .Case(
"vectorize_width", LoopHintAttr::VectorizeWidth)
146 .Case(
"interleave", LoopHintAttr::Interleave)
147 .Case(
"interleave_count", LoopHintAttr::InterleaveCount)
148 .Case(
"unroll", LoopHintAttr::Unroll)
149 .Case(
"unroll_count", LoopHintAttr::UnrollCount)
150 .Case(
"pipeline", LoopHintAttr::PipelineDisabled)
151 .Case(
"pipeline_initiation_interval",
152 LoopHintAttr::PipelineInitiationInterval)
153 .Case(
"distribute", LoopHintAttr::Distribute)
154 .Default(LoopHintAttr::Vectorize);
155 if (Option == LoopHintAttr::VectorizeWidth ||
156 Option == LoopHintAttr::InterleaveCount ||
157 Option == LoopHintAttr::UnrollCount ||
158 Option == LoopHintAttr::PipelineInitiationInterval) {
159 assert(ValueExpr &&
"Attribute must have a valid value expression.");
162 State = LoopHintAttr::Numeric;
163 }
else if (Option == LoopHintAttr::Vectorize ||
164 Option == LoopHintAttr::Interleave ||
165 Option == LoopHintAttr::Unroll ||
166 Option == LoopHintAttr::Distribute ||
167 Option == LoopHintAttr::PipelineDisabled) {
168 assert(StateLoc && StateLoc->
Ident &&
"Loop hint must have an argument");
170 State = LoopHintAttr::Disable;
171 else if (StateLoc->
Ident->
isStr(
"assume_safety"))
172 State = LoopHintAttr::AssumeSafety;
174 State = LoopHintAttr::Full;
176 State = LoopHintAttr::Enable;
178 llvm_unreachable(
"bad loop hint argument");
180 llvm_unreachable(
"bad loop hint");
183 return LoopHintAttr::CreateImplicit(S.
Context, Spelling, Option, State,
200 const LoopHintAttr *StateAttr;
201 const LoopHintAttr *NumericAttr;
202 } HintAttrs[] = {{
nullptr,
nullptr}, {
nullptr,
nullptr}, {
nullptr,
nullptr},
203 {
nullptr,
nullptr}, {
nullptr,
nullptr}, {
nullptr,
nullptr}};
205 for (
const auto *I : Attrs) {
206 const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I);
212 LoopHintAttr::OptionType Option = LH->getOption();
222 case LoopHintAttr::Vectorize:
223 case LoopHintAttr::VectorizeWidth:
224 Category = Vectorize;
226 case LoopHintAttr::Interleave:
227 case LoopHintAttr::InterleaveCount:
228 Category = Interleave;
230 case LoopHintAttr::Unroll:
231 case LoopHintAttr::UnrollCount:
234 case LoopHintAttr::UnrollAndJam:
235 case LoopHintAttr::UnrollAndJamCount:
236 Category = UnrollAndJam;
238 case LoopHintAttr::Distribute:
240 Category = Distribute;
242 case LoopHintAttr::PipelineDisabled:
243 case LoopHintAttr::PipelineInitiationInterval:
248 assert(Category <
sizeof(HintAttrs) /
sizeof(HintAttrs[0]));
249 auto &CategoryState = HintAttrs[
Category];
250 const LoopHintAttr *PrevAttr;
251 if (Option == LoopHintAttr::Vectorize ||
252 Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll ||
253 Option == LoopHintAttr::UnrollAndJam ||
254 Option == LoopHintAttr::PipelineDisabled ||
255 Option == LoopHintAttr::Distribute) {
257 PrevAttr = CategoryState.StateAttr;
258 CategoryState.StateAttr = LH;
261 PrevAttr = CategoryState.NumericAttr;
262 CategoryState.NumericAttr = LH;
269 S.
Diag(OptionLoc, diag::err_pragma_loop_compatibility)
270 <<
true << PrevAttr->getDiagnosticName(Policy)
271 << LH->getDiagnosticName(Policy);
273 if (CategoryState.StateAttr && CategoryState.NumericAttr &&
274 (Category == Unroll || Category == UnrollAndJam ||
275 CategoryState.StateAttr->getState() == LoopHintAttr::Disable)) {
280 S.
Diag(OptionLoc, diag::err_pragma_loop_compatibility)
282 << CategoryState.StateAttr->getDiagnosticName(Policy)
283 << CategoryState.NumericAttr->getDiagnosticName(Policy);
299 S.
Diag(A.
getLoc(), diag::err_attribute_too_many_arguments) << A << 1;
303 unsigned UnrollFactor = 0;
307 llvm::APSInt ArgVal(32);
310 S.
Diag(A.
getLoc(), diag::err_attribute_argument_type)
315 int Val = ArgVal.getSExtValue();
319 diag::err_attribute_requires_positive_integer)
326 return OpenCLUnrollHintAttr::CreateImplicit(S.
Context, UnrollFactor);
334 ? (unsigned)diag::warn_unhandled_ms_attribute_ignored
335 : (
unsigned)diag::warn_unknown_attribute_ignored)
338 case ParsedAttr::AT_FallThrough:
340 case ParsedAttr::AT_LoopHint:
342 case ParsedAttr::AT_OpenCLUnrollHint:
344 case ParsedAttr::AT_Suppress:
369 return ActOnAttributedStmt(Range.
getBegin(), Attrs, S);
Defines the clang::ASTContext interface.
const char * getSpelling() const
bool CheckLoopHintExpr(Expr *E, SourceLocation Loc)
bool isDeclspecAttribute() const
static void CheckForIncompatibleAttributes(Sema &S, const SmallVectorImpl< const Attr *> &Attrs)
Stmt - This represents one statement.
Defines the SourceManager interface.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Expr * getArgAsExpr(unsigned Arg) const
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
static Attr * handleFallThroughAttr(Sema &S, Stmt *St, const ParsedAttr &A, SourceRange Range)
bool isCXX11Attribute() const
Describes how types, statements, expressions, and declarations should be printed. ...
unsigned getAttributeSpellingListIndex() const
Get an index into the attribute spelling list defined in Attr.td.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
const LangOptions & getLangOpts() const
Sema - This implements semantic analysis and AST building for C.
static Attr * handleSuppressAttr(Sema &S, Stmt *St, const ParsedAttr &A, SourceRange Range)
This represents one expression.
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
SourceLocation getEnd() const
Wraps an identifier and optional source location for the identifier.
static Attr * ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A, SourceRange Range)
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Encodes a location in the source.
ParsedAttr - Represents a syntactic attribute.
SourceRange getRange() const
StringRef getName() const
Return the actual identifier string.
Dataflow Directional Tag Classes.
StmtClass getStmtClass() const
SourceLocation getLoc() const
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return true if this expression is a valid integer constant expression...
IdentifierInfo * getName() 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.
StmtResult ProcessStmtAttributes(Stmt *Stmt, const ParsedAttributesView &Attrs, SourceRange Range)
Stmt attributes - this routine is the top level dispatcher.
sema::FunctionScopeInfo * getCurFunction() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
static Attr * handleOpenCLUnrollHint(Sema &S, Stmt *St, const ParsedAttr &A, SourceRange Range)
bool checkStringLiteralArgumentAttr(const ParsedAttr &Attr, unsigned ArgNum, StringRef &Str, SourceLocation *ArgLocation=nullptr)
Check if the argument ArgNum of Attr is a ASCII string literal.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
const LangOptions & getLangOpts() const
IdentifierLoc * getArgAsIdent(unsigned Arg) const
static Attr * handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A, SourceRange)
Attr - This represents one attribute.
IdentifierInfo * getScopeName() const