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 AttributeList::AT_FallThrough:
301 case AttributeList::AT_LoopHint:
303 case AttributeList::AT_OpenCLUnrollHint:
305 case AttributeList::AT_Suppress:
329 return ActOnAttributedStmt(Range.
getBegin(), Attrs, S);
Defines the clang::ASTContext interface.
const char * getSpelling() const
bool CheckLoopHintExpr(Expr *E, SourceLocation Loc)
AttributeList * getNext() const
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
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.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
Describes how types, statements, expressions, and declarations should be printed. ...
SourceLocation getLoc() const
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
static Attr * handleSuppressAttr(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range)
IdentifierLoc * getArgAsIdent(unsigned Arg) const
unsigned getAttributeSpellingListIndex() const
Get an index into the attribute spelling list defined in Attr.td.
const LangOptions & getLangOpts() const
Sema - This implements semantic analysis and AST building for C.
Expr - This represents one expression.
static Attr * handleFallThroughAttr(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range)
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
SourceLocation getEnd() const
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.
bool isCXX11Attribute() const
SourceRange getRange() const
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Encodes a location in the source.
IdentifierInfo * getScopeName() const
static Attr * handleOpenCLUnrollHint(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range)
static Attr * ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A, SourceRange Range)
bool isDeclspecAttribute() const
StringRef getName() const
Return the actual identifier 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.
Dataflow Directional Tag Classes.
Expr * getArgAsExpr(unsigned Arg) const
StmtClass getStmtClass() 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.
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 * handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A, SourceRange)
A trivial tuple used to represent a source range.
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation getBegin() const
const LangOptions & getLangOpts() const
Attr - This represents one attribute.
AttributeList - Represents a syntactic attribute.