21 #include "llvm/ADT/StringExtras.h" 23 using namespace clang;
30 if (!isa<NullStmt>(St)) {
33 if (isa<SwitchCase>(St)) {
35 S.
Diag(L, diag::note_fallthrough_insert_semi_fixit)
41 if (FnScope->SwitchStack.empty()) {
52 FnScope->setHasFallthroughStmt();
59 S.
Diag(A.
getLoc(), diag::err_attribute_too_few_arguments)
64 std::vector<StringRef> DiagnosticIdentifiers;
65 for (
unsigned I = 0, E = A.
getNumArgs(); I != E; ++I) {
73 DiagnosticIdentifiers.push_back(RuleName);
76 return ::new (S.
Context) SuppressAttr(
88 bool PragmaUnroll = PragmaNameLoc->
Ident->
getName() ==
"unroll";
89 bool PragmaNoUnroll = PragmaNameLoc->
Ident->
getName() ==
"nounroll";
95 llvm::StringSwitch<const char *>(PragmaNameLoc->
Ident->
getName())
96 .Case(
"unroll",
"#pragma unroll")
97 .Case(
"nounroll",
"#pragma nounroll")
98 .Default(
"#pragma clang loop");
99 S.
Diag(St->
getLocStart(), diag::err_pragma_loop_precedes_nonloop) << Pragma;
103 LoopHintAttr::Spelling Spelling =
105 LoopHintAttr::OptionType Option;
106 LoopHintAttr::LoopHintState
State;
107 if (PragmaNoUnroll) {
109 Option = LoopHintAttr::Unroll;
110 State = LoopHintAttr::Disable;
111 }
else if (PragmaUnroll) {
114 Option = LoopHintAttr::UnrollCount;
115 State = LoopHintAttr::Numeric;
118 Option = LoopHintAttr::Unroll;
119 State = LoopHintAttr::Enable;
123 assert(OptionLoc && OptionLoc->
Ident &&
124 "Attribute must have valid option info.");
125 Option = llvm::StringSwitch<LoopHintAttr::OptionType>(
127 .Case(
"vectorize", LoopHintAttr::Vectorize)
128 .Case(
"vectorize_width", LoopHintAttr::VectorizeWidth)
129 .Case(
"interleave", LoopHintAttr::Interleave)
130 .Case(
"interleave_count", LoopHintAttr::InterleaveCount)
131 .Case(
"unroll", LoopHintAttr::Unroll)
132 .Case(
"unroll_count", LoopHintAttr::UnrollCount)
133 .Case(
"distribute", LoopHintAttr::Distribute)
134 .Default(LoopHintAttr::Vectorize);
135 if (Option == LoopHintAttr::VectorizeWidth ||
136 Option == LoopHintAttr::InterleaveCount ||
137 Option == LoopHintAttr::UnrollCount) {
138 assert(ValueExpr &&
"Attribute must have a valid value expression.");
141 State = LoopHintAttr::Numeric;
142 }
else if (Option == LoopHintAttr::Vectorize ||
143 Option == LoopHintAttr::Interleave ||
144 Option == LoopHintAttr::Unroll ||
145 Option == LoopHintAttr::Distribute) {
146 assert(StateLoc && StateLoc->
Ident &&
"Loop hint must have an argument");
148 State = LoopHintAttr::Disable;
149 else if (StateLoc->
Ident->
isStr(
"assume_safety"))
150 State = LoopHintAttr::AssumeSafety;
152 State = LoopHintAttr::Full;
154 State = LoopHintAttr::Enable;
156 llvm_unreachable(
"bad loop hint argument");
158 llvm_unreachable(
"bad loop hint");
161 return LoopHintAttr::CreateImplicit(S.
Context, Spelling, Option, State,
177 const LoopHintAttr *StateAttr;
178 const LoopHintAttr *NumericAttr;
179 } HintAttrs[] = {{
nullptr,
nullptr},
184 for (
const auto *I : Attrs) {
185 const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I);
191 LoopHintAttr::OptionType Option = LH->getOption();
192 enum { Vectorize, Interleave, Unroll, Distribute }
Category;
194 case LoopHintAttr::Vectorize:
195 case LoopHintAttr::VectorizeWidth:
196 Category = Vectorize;
198 case LoopHintAttr::Interleave:
199 case LoopHintAttr::InterleaveCount:
200 Category = Interleave;
202 case LoopHintAttr::Unroll:
203 case LoopHintAttr::UnrollCount:
206 case LoopHintAttr::Distribute:
208 Category = Distribute;
212 auto &CategoryState = HintAttrs[
Category];
213 const LoopHintAttr *PrevAttr;
214 if (Option == LoopHintAttr::Vectorize ||
215 Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll ||
216 Option == LoopHintAttr::Distribute) {
218 PrevAttr = CategoryState.StateAttr;
219 CategoryState.StateAttr = LH;
222 PrevAttr = CategoryState.NumericAttr;
223 CategoryState.NumericAttr = LH;
230 S.
Diag(OptionLoc, diag::err_pragma_loop_compatibility)
231 <<
true << PrevAttr->getDiagnosticName(Policy)
232 << LH->getDiagnosticName(Policy);
234 if (CategoryState.StateAttr && CategoryState.NumericAttr &&
235 (Category == Unroll ||
236 CategoryState.StateAttr->getState() == LoopHintAttr::Disable)) {
241 S.
Diag(OptionLoc, diag::err_pragma_loop_compatibility)
243 << CategoryState.StateAttr->getDiagnosticName(Policy)
244 << CategoryState.NumericAttr->getDiagnosticName(Policy);
265 unsigned UnrollFactor = 0;
269 llvm::APSInt ArgVal(32);
272 S.
Diag(A.
getLoc(), diag::err_attribute_argument_type)
277 int Val = ArgVal.getSExtValue();
281 diag::err_attribute_requires_positive_integer)
288 return OpenCLUnrollHintAttr::CreateImplicit(S.
Context, UnrollFactor);
296 diag::warn_unhandled_ms_attribute_ignored :
297 diag::warn_unknown_attribute_ignored) << A.
getName();
299 case ParsedAttr::AT_FallThrough:
301 case ParsedAttr::AT_LoopHint:
303 case ParsedAttr::AT_OpenCLUnrollHint:
305 case ParsedAttr::AT_Suppress:
330 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.
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)
Expr - 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.
SourceLocation getLocStart() const LLVM_READONLY
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