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;
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;
104 LoopHintAttr::OptionType Option;
105 LoopHintAttr::LoopHintState
State;
106 if (PragmaNoUnroll) {
108 Spelling = LoopHintAttr::Pragma_nounroll;
109 Option = LoopHintAttr::Unroll;
110 State = LoopHintAttr::Disable;
111 }
else if (PragmaUnroll) {
112 Spelling = LoopHintAttr::Pragma_unroll;
115 Option = LoopHintAttr::UnrollCount;
116 State = LoopHintAttr::Numeric;
119 Option = LoopHintAttr::Unroll;
120 State = LoopHintAttr::Enable;
124 Spelling = LoopHintAttr::Pragma_clang_loop;
125 assert(OptionLoc && OptionLoc->
Ident &&
126 "Attribute must have valid option info.");
127 Option = llvm::StringSwitch<LoopHintAttr::OptionType>(
129 .Case(
"vectorize", LoopHintAttr::Vectorize)
130 .Case(
"vectorize_width", LoopHintAttr::VectorizeWidth)
131 .Case(
"interleave", LoopHintAttr::Interleave)
132 .Case(
"interleave_count", LoopHintAttr::InterleaveCount)
133 .Case(
"unroll", LoopHintAttr::Unroll)
134 .Case(
"unroll_count", LoopHintAttr::UnrollCount)
135 .Case(
"distribute", LoopHintAttr::Distribute)
136 .Default(LoopHintAttr::Vectorize);
137 if (Option == LoopHintAttr::VectorizeWidth ||
138 Option == LoopHintAttr::InterleaveCount ||
139 Option == LoopHintAttr::UnrollCount) {
140 assert(ValueExpr &&
"Attribute must have a valid value expression.");
143 State = LoopHintAttr::Numeric;
144 }
else if (Option == LoopHintAttr::Vectorize ||
145 Option == LoopHintAttr::Interleave ||
146 Option == LoopHintAttr::Unroll ||
147 Option == LoopHintAttr::Distribute) {
148 assert(StateLoc && StateLoc->
Ident &&
"Loop hint must have an argument");
150 State = LoopHintAttr::Disable;
151 else if (StateLoc->
Ident->
isStr(
"assume_safety"))
152 State = LoopHintAttr::AssumeSafety;
154 State = LoopHintAttr::Full;
156 State = LoopHintAttr::Enable;
158 llvm_unreachable(
"bad loop hint argument");
160 llvm_unreachable(
"bad loop hint");
163 return LoopHintAttr::CreateImplicit(S.
Context, Spelling, Option, State,
179 const LoopHintAttr *StateAttr;
180 const LoopHintAttr *NumericAttr;
181 } HintAttrs[] = {{
nullptr,
nullptr},
186 for (
const auto *
I : Attrs) {
187 const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(
I);
193 LoopHintAttr::OptionType Option = LH->getOption();
194 enum { Vectorize, Interleave, Unroll, Distribute }
Category;
196 case LoopHintAttr::Vectorize:
197 case LoopHintAttr::VectorizeWidth:
200 case LoopHintAttr::Interleave:
201 case LoopHintAttr::InterleaveCount:
204 case LoopHintAttr::Unroll:
205 case LoopHintAttr::UnrollCount:
208 case LoopHintAttr::Distribute:
214 auto &CategoryState = HintAttrs[
Category];
215 const LoopHintAttr *PrevAttr;
216 if (Option == LoopHintAttr::Vectorize ||
217 Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll ||
218 Option == LoopHintAttr::Distribute) {
220 PrevAttr = CategoryState.StateAttr;
221 CategoryState.StateAttr = LH;
224 PrevAttr = CategoryState.NumericAttr;
225 CategoryState.NumericAttr = LH;
232 S.
Diag(OptionLoc, diag::err_pragma_loop_compatibility)
233 <<
true << PrevAttr->getDiagnosticName(Policy)
234 << LH->getDiagnosticName(Policy);
236 if (CategoryState.StateAttr && CategoryState.NumericAttr &&
238 CategoryState.StateAttr->getState() == LoopHintAttr::Disable)) {
243 S.
Diag(OptionLoc, diag::err_pragma_loop_compatibility)
245 << CategoryState.StateAttr->getDiagnosticName(Policy)
246 << CategoryState.NumericAttr->getDiagnosticName(Policy);
267 unsigned UnrollFactor = 0;
271 llvm::APSInt ArgVal(32);
274 S.
Diag(A.
getLoc(), diag::err_attribute_argument_type)
279 int Val = ArgVal.getSExtValue();
283 diag::err_attribute_requires_positive_integer)
290 return OpenCLUnrollHintAttr::CreateImplicit(S.
Context, UnrollFactor);
298 diag::warn_unhandled_ms_attribute_ignored :
299 diag::warn_unknown_attribute_ignored) << A.
getName();
301 case AttributeList::AT_FallThrough:
303 case AttributeList::AT_LoopHint:
305 case AttributeList::AT_OpenCLUnrollHint:
307 case AttributeList::AT_Suppress:
331 return ActOnAttributedStmt(Range.
getBegin(), Attrs,
S);
Defines the clang::ASTContext interface.
SourceLocation getEnd() const
StmtClass getStmtClass() const
bool CheckLoopHintExpr(Expr *E, SourceLocation Loc)
const LangOptions & getLangOpts() const
Stmt - This represents one statement.
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()
Describes how types, statements, expressions, and declarations should be printed. ...
const LangOptions & getLangOpts() const
static Attr * handleSuppressAttr(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range)
detail::InMemoryDirectory::const_iterator I
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
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.
const char * getSpelling() const
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Encodes a location in the source.
static Attr * handleOpenCLUnrollHint(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range)
static void CheckForIncompatibleAttributes(Sema &S, const SmallVectorImpl< const Attr * > &Attrs)
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...
static Attr * ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range)
SourceLocation getBegin() const
IdentifierInfo * getScopeName() 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.
bool checkStringLiteralArgumentAttr(const AttributeList &Attr, unsigned ArgNum, StringRef &Str, SourceLocation *ArgLocation=nullptr)
Check if the argument ArgNum of Attr is a ASCII string literal.
Expr * getArgAsExpr(unsigned Arg) const
detail::InMemoryDirectory::const_iterator E
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 isCXX11Attribute() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
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.
SourceLocation getLocStart() const LLVM_READONLY
Attr - This represents one attribute.
AttributeList - Represents a syntactic attribute.