let Documentation = [Undocumented];
}
-def Unaligned : IgnoredAttr {\r
- let Spellings = [Keyword<"__unaligned">];\r
-}\r
-\r
-def LoopHint : Attr {\r
- /// vectorize: vectorizes loop operations if 'value != 0'.\r
- /// vectorize_width: vectorize loop operations with width 'value'.\r
- /// interleave: interleave multiple loop iterations if 'value != 0'.\r
- /// interleave_count: interleaves 'value' loop interations.\r
-\r
- /// FIXME: Add Pragma spelling to tablegen and\r
- /// use it here.\r
- let Spellings = [Keyword<"loop">];\r
-\r
- /// State of the loop optimization specified by the spelling.\r
- let Args = [EnumArgument<"Option", "OptionType",\r
- ["vectorize", "vectorize_width", "interleave", "interleave_count"],\r
- ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount"]>,\r
- DefaultIntArgument<"Value", 1>];\r
-\r
- let AdditionalMembers = [{\r
- static StringRef getOptionName(int Option) {\r
- switch(Option) {\r
- case Vectorize: return "vectorize";\r
- case VectorizeWidth: return "vectorize_width";\r
- case Interleave: return "interleave";\r
- case InterleaveCount: return "interleave_count";\r
- }\r
- llvm_unreachable("Unhandled LoopHint option.");\r
- }\r
-\r
- static StringRef getValueName(int Value) {\r
- if (Value)\r
- return "enable";\r
- return "disable";\r
- }\r
-\r
- // FIXME: Modify pretty printer to print this pragma.\r
- void print(raw_ostream &OS, const PrintingPolicy &Policy) const {\r
- OS << "#pragma clang loop " << getOptionName(option) << "(";\r
- if (option == VectorizeWidth || option == InterleaveCount)\r
- OS << value;\r
- else\r
- OS << getValueName(value);\r
- OS << ")\n";\r
- }\r
- }];\r
-\r
- let Documentation = [Undocumented];\r
-}\r
+def Unaligned : IgnoredAttr {
+ let Spellings = [Keyword<"__unaligned">];
+}
+
+def LoopHint : Attr {
+ /// vectorize: vectorizes loop operations if 'value != 0'.
+ /// vectorize_width: vectorize loop operations with width 'value'.
+ /// interleave: interleave multiple loop iterations if 'value != 0'.
+ /// interleave_count: interleaves 'value' loop interations.
+
+ /// FIXME: Add Pragma spelling to tablegen and
+ /// use it here.
+ let Spellings = [Keyword<"loop">];
+
+ /// State of the loop optimization specified by the spelling.
+ let Args = [EnumArgument<"Option", "OptionType",
+ ["vectorize", "vectorize_width", "interleave", "interleave_count"],
+ ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount"]>,
+ DefaultIntArgument<"Value", 1>];
+
+ let AdditionalMembers = [{
+ static StringRef getOptionName(int Option) {
+ switch(Option) {
+ case Vectorize: return "vectorize";
+ case VectorizeWidth: return "vectorize_width";
+ case Interleave: return "interleave";
+ case InterleaveCount: return "interleave_count";
+ }
+ llvm_unreachable("Unhandled LoopHint option.");
+ }
+
+ static StringRef getValueName(int Value) {
+ if (Value)
+ return "enable";
+ return "disable";
+ }
+
+ // FIXME: Modify pretty printer to print this pragma.
+ void print(raw_ostream &OS, const PrintingPolicy &Policy) const {
+ OS << "#pragma clang loop " << getOptionName(option) << "(";
+ if (option == VectorizeWidth || option == InterleaveCount)
+ OS << value;
+ else
+ OS << getValueName(value);
+ OS << ")\n";
+ }
+ }];
+
+ let Documentation = [Undocumented];
+}
def err_omp_expected_punc : Error<
"expected ',' or ')' in '%0' clause">;
def err_omp_unexpected_clause : Error<
- "unexpected OpenMP clause '%0' in directive '#pragma omp %1'">;\r
-def err_omp_more_one_clause : Error<\r
- "directive '#pragma omp %0' cannot contain more than one '%1' clause">;\r
-\r
-// Pragma loop support.\r
-def err_pragma_loop_invalid_option : Error<\r
- "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, vectorize_width, interleave, or interleave_count">;\r
-} // end of Parse Issue category.\r
-\r
-let CategoryName = "Modules Issue" in {\r
+ "unexpected OpenMP clause '%0' in directive '#pragma omp %1'">;
+def err_omp_more_one_clause : Error<
+ "directive '#pragma omp %0' cannot contain more than one '%1' clause">;
+
+// Pragma loop support.
+def err_pragma_loop_invalid_option : Error<
+ "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, vectorize_width, interleave, or interleave_count">;
+} // end of Parse Issue category.
+
+let CategoryName = "Modules Issue" in {
def err_module_expected_ident : Error<
"expected a module name after module import">;
def err_module_expected_semi : Error<
def note_surrounding_namespace_ends_here : Note<
"surrounding namespace with visibility attribute ends here">;
def err_pragma_pop_visibility_mismatch : Error<
- "#pragma visibility pop with no matching #pragma visibility push">;\r
-def note_surrounding_namespace_starts_here : Note<\r
- "surrounding namespace with visibility attribute starts here">;\r
-def err_pragma_loop_invalid_value : Error<\r
- "%select{invalid|missing}0 value%select{ %1|}0; expected a positive integer value">;\r
-def err_pragma_loop_invalid_keyword : Error<\r
- "%select{invalid|missing}0 keyword%select{ %1|}0; expected 'enable' or 'disable'">;\r
-def err_pragma_loop_compatibility : Error<\r
- "%select{incompatible|duplicate}0 directives '%1(%2)' and '%3(%4)'">;\r
-def err_pragma_loop_precedes_nonloop : Error<\r
- "expected a for, while, or do-while loop to follow the '#pragma clang loop' "\r
- "directive">;\r
-\r
-/// Objective-C parser diagnostics\r
-def err_duplicate_class_def : Error<\r
+ "#pragma visibility pop with no matching #pragma visibility push">;
+def note_surrounding_namespace_starts_here : Note<
+ "surrounding namespace with visibility attribute starts here">;
+def err_pragma_loop_invalid_value : Error<
+ "%select{invalid|missing}0 value%select{ %1|}0; expected a positive integer value">;
+def err_pragma_loop_invalid_keyword : Error<
+ "%select{invalid|missing}0 keyword%select{ %1|}0; expected 'enable' or 'disable'">;
+def err_pragma_loop_compatibility : Error<
+ "%select{incompatible|duplicate}0 directives '%1(%2)' and '%3(%4)'">;
+def err_pragma_loop_precedes_nonloop : Error<
+ "expected a for, while, or do-while loop to follow the '#pragma clang loop' "
+ "directive">;
+
+/// Objective-C parser diagnostics
+def err_duplicate_class_def : Error<
"duplicate interface definition for class %0">;
def err_undef_superclass : Error<
"cannot find interface declaration for %0, superclass of %1">;
//===----------------------------------------------------------------------===//
#include "RAIIObjectsForParser.h"
-#include "clang/Lex/Preprocessor.h"\r
-#include "clang/Parse/ParseDiagnostic.h"\r
-#include "clang/Parse/Parser.h"\r
-#include "clang/Sema/LoopHint.h"\r
-#include "clang/Sema/Scope.h"\r
-#include "llvm/ADT/StringSwitch.h"\r
-using namespace clang;\r
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/Parser.h"
+#include "clang/Sema/LoopHint.h"
+#include "clang/Sema/Scope.h"
+#include "llvm/ADT/StringSwitch.h"
+using namespace clang;
namespace {
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &FirstToken) override;
private:
- Sema &Actions;\r
-};\r
-\r
-struct PragmaLoopHintHandler : public PragmaHandler {\r
- PragmaLoopHintHandler() : PragmaHandler("loop") {}\r
- void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,\r
- Token &FirstToken) override;\r
-};\r
-\r
-} // end namespace\r
-\r
-void Parser::initializePragmaHandlers() {\r
+ Sema &Actions;
+};
+
+struct PragmaLoopHintHandler : public PragmaHandler {
+ PragmaLoopHintHandler() : PragmaHandler("loop") {}
+ void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &FirstToken) override;
+};
+
+} // end namespace
+
+void Parser::initializePragmaHandlers() {
AlignHandler.reset(new PragmaAlignHandler());
PP.AddPragmaHandler(AlignHandler.get());
MSSection.reset(new PragmaMSPragma("section"));
PP.AddPragmaHandler(MSSection.get());
}
-\r
- OptimizeHandler.reset(new PragmaOptimizeHandler(Actions));\r
- PP.AddPragmaHandler("clang", OptimizeHandler.get());\r
-\r
- LoopHintHandler.reset(new PragmaLoopHintHandler());\r
- PP.AddPragmaHandler("clang", LoopHintHandler.get());\r
-}\r
-\r
-void Parser::resetPragmaHandlers() {\r
+
+ OptimizeHandler.reset(new PragmaOptimizeHandler(Actions));
+ PP.AddPragmaHandler("clang", OptimizeHandler.get());
+
+ LoopHintHandler.reset(new PragmaLoopHintHandler());
+ PP.AddPragmaHandler("clang", LoopHintHandler.get());
+}
+
+void Parser::resetPragmaHandlers() {
// Remove the pragma handlers we installed.
PP.RemovePragmaHandler(AlignHandler.get());
AlignHandler.reset();
PP.RemovePragmaHandler("STDC", FPContractHandler.get());
FPContractHandler.reset();
-\r
- PP.RemovePragmaHandler("clang", OptimizeHandler.get());\r
- OptimizeHandler.reset();\r
-\r
- PP.RemovePragmaHandler("clang", LoopHintHandler.get());\r
- LoopHintHandler.reset();\r
-}\r
-\r
-/// \brief Handle the annotation token produced for #pragma unused(...)\r
+
+ PP.RemovePragmaHandler("clang", OptimizeHandler.get());
+ OptimizeHandler.reset();
+
+ PP.RemovePragmaHandler("clang", LoopHintHandler.get());
+ LoopHintHandler.reset();
+}
+
+/// \brief Handle the annotation token produced for #pragma unused(...)
///
/// Each annot_pragma_unused is followed by the argument token so e.g.
/// "#pragma unused(x,y)" becomes:
unsigned Parser::HandlePragmaMSInitSeg(llvm::StringRef PragmaName,
SourceLocation PragmaLocation) {
return PP.getDiagnostics().getCustomDiagID(
- DiagnosticsEngine::Error, "'#pragma %0' not implemented.");\r
-}\r
-\r
-struct PragmaLoopHintInfo {\r
- Token Loop;\r
- Token Value;\r
- Token Option;\r
-};\r
-\r
-LoopHint Parser::HandlePragmaLoopHint() {\r
- assert(Tok.is(tok::annot_pragma_loop_hint));\r
- PragmaLoopHintInfo *Info =\r
- static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());\r
-\r
- LoopHint Hint;\r
- Hint.LoopLoc =\r
- IdentifierLoc::create(Actions.Context, Info->Loop.getLocation(),\r
- Info->Loop.getIdentifierInfo());\r
- Hint.OptionLoc =\r
- IdentifierLoc::create(Actions.Context, Info->Option.getLocation(),\r
- Info->Option.getIdentifierInfo());\r
- Hint.ValueLoc =\r
- IdentifierLoc::create(Actions.Context, Info->Value.getLocation(),\r
- Info->Value.getIdentifierInfo());\r
- Hint.Range =\r
- SourceRange(Info->Option.getLocation(), Info->Value.getLocation());\r
-\r
- // FIXME: We should support template parameters for the loop hint value.\r
- // See bug report #19610\r
- if (Info->Value.is(tok::numeric_constant))\r
- Hint.ValueExpr = Actions.ActOnNumericConstant(Info->Value).get();\r
- else\r
- Hint.ValueExpr = nullptr;\r
-\r
- return Hint;\r
-}\r
-\r
-// #pragma GCC visibility comes in two variants:\r
-// 'push' '(' [visibility] ')'\r
-// 'pop'\r
+ DiagnosticsEngine::Error, "'#pragma %0' not implemented.");
+}
+
+struct PragmaLoopHintInfo {
+ Token Loop;
+ Token Value;
+ Token Option;
+};
+
+LoopHint Parser::HandlePragmaLoopHint() {
+ assert(Tok.is(tok::annot_pragma_loop_hint));
+ PragmaLoopHintInfo *Info =
+ static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
+
+ LoopHint Hint;
+ Hint.LoopLoc =
+ IdentifierLoc::create(Actions.Context, Info->Loop.getLocation(),
+ Info->Loop.getIdentifierInfo());
+ Hint.OptionLoc =
+ IdentifierLoc::create(Actions.Context, Info->Option.getLocation(),
+ Info->Option.getIdentifierInfo());
+ Hint.ValueLoc =
+ IdentifierLoc::create(Actions.Context, Info->Value.getLocation(),
+ Info->Value.getIdentifierInfo());
+ Hint.Range =
+ SourceRange(Info->Option.getLocation(), Info->Value.getLocation());
+
+ // FIXME: We should support template parameters for the loop hint value.
+ // See bug report #19610
+ if (Info->Value.is(tok::numeric_constant))
+ Hint.ValueExpr = Actions.ActOnNumericConstant(Info->Value).get();
+ else
+ Hint.ValueExpr = nullptr;
+
+ return Hint;
+}
+
+// #pragma GCC visibility comes in two variants:
+// 'push' '(' [visibility] ')'
+// 'pop'
void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
PragmaIntroducerKind Introducer,
Token &VisTok) {
<< PP.getSpelling(Tok);
return;
}
-\r
- Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());\r
-}\r
-\r
-/// \brief Handle the \#pragma clang loop directive.\r
-/// #pragma clang 'loop' loop-hints\r
-///\r
-/// loop-hints:\r
-/// loop-hint loop-hints[opt]\r
-///\r
-/// loop-hint:\r
-/// 'vectorize' '(' loop-hint-keyword ')'\r
-/// 'interleave' '(' loop-hint-keyword ')'\r
-/// 'vectorize_width' '(' loop-hint-value ')'\r
-/// 'interleave_count' '(' loop-hint-value ')'\r
-///\r
-/// loop-hint-keyword:\r
-/// 'enable'\r
-/// 'disable'\r
-///\r
-/// loop-hint-value:\r
-/// constant-expression\r
-///\r
-/// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to\r
-/// try vectorizing the instructions of the loop it precedes. Specifying\r
-/// interleave(enable) or interleave_count(_value_) instructs llvm to try\r
-/// interleaving multiple iterations of the loop it precedes. The width of the\r
-/// vector instructions is specified by vectorize_width() and the number of\r
-/// interleaved loop iterations is specified by interleave_count(). Specifying a\r
-/// value of 1 effectively disables vectorization/interleaving, even if it is\r
-/// possible and profitable, and 0 is invalid. The loop vectorizer currently\r
-/// only works on inner loops.\r
-///\r
-void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,\r
- PragmaIntroducerKind Introducer,\r
- Token &Tok) {\r
- Token Loop = Tok;\r
- SmallVector<Token, 1> TokenList;\r
-\r
- // Lex the optimization option and verify it is an identifier.\r
- PP.Lex(Tok);\r
- if (Tok.isNot(tok::identifier)) {\r
- PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)\r
- << /*MissingOption=*/true << "";\r
- return;\r
- }\r
-\r
- while (Tok.is(tok::identifier)) {\r
- Token Option = Tok;\r
- IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();\r
-\r
- if (!OptionInfo->isStr("vectorize") && !OptionInfo->isStr("interleave") &&\r
- !OptionInfo->isStr("vectorize_width") &&\r
- !OptionInfo->isStr("interleave_count")) {\r
- PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)\r
- << /*MissingOption=*/false << OptionInfo;\r
- return;\r
- }\r
-\r
- // Read '('\r
- PP.Lex(Tok);\r
- if (Tok.isNot(tok::l_paren)) {\r
- PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;\r
- return;\r
- }\r
-\r
- // FIXME: All tokens between '(' and ')' should be stored and parsed as a\r
- // constant expression.\r
- PP.Lex(Tok);\r
- Token Value;\r
- if (Tok.is(tok::identifier) || Tok.is(tok::numeric_constant))\r
- Value = Tok;\r
-\r
- // Read ')'\r
- PP.Lex(Tok);\r
- if (Tok.isNot(tok::r_paren)) {\r
- PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;\r
- return;\r
- }\r
-\r
- // Get next optimization option.\r
- PP.Lex(Tok);\r
-\r
- auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;\r
- Info->Loop = Loop;\r
- Info->Option = Option;\r
- Info->Value = Value;\r
-\r
- // Generate the vectorization hint token.\r
- Token LoopHintTok;\r
- LoopHintTok.startToken();\r
- LoopHintTok.setKind(tok::annot_pragma_loop_hint);\r
- LoopHintTok.setLocation(Loop.getLocation());\r
- LoopHintTok.setAnnotationValue(static_cast<void *>(Info));\r
- TokenList.push_back(LoopHintTok);\r
- }\r
-\r
- if (Tok.isNot(tok::eod)) {\r
- PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)\r
- << "clang loop";\r
- return;\r
- }\r
-\r
- Token *TokenArray = new Token[TokenList.size()];\r
- std::copy(TokenList.begin(), TokenList.end(), TokenArray);\r
-\r
- PP.EnterTokenStream(TokenArray, TokenList.size(),\r
- /*DisableMacroExpansion=*/false,\r
- /*OwnsTokens=*/true);\r
-}\r
+
+ Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
+}
+
+/// \brief Handle the \#pragma clang loop directive.
+/// #pragma clang 'loop' loop-hints
+///
+/// loop-hints:
+/// loop-hint loop-hints[opt]
+///
+/// loop-hint:
+/// 'vectorize' '(' loop-hint-keyword ')'
+/// 'interleave' '(' loop-hint-keyword ')'
+/// 'vectorize_width' '(' loop-hint-value ')'
+/// 'interleave_count' '(' loop-hint-value ')'
+///
+/// loop-hint-keyword:
+/// 'enable'
+/// 'disable'
+///
+/// loop-hint-value:
+/// constant-expression
+///
+/// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
+/// try vectorizing the instructions of the loop it precedes. Specifying
+/// interleave(enable) or interleave_count(_value_) instructs llvm to try
+/// interleaving multiple iterations of the loop it precedes. The width of the
+/// vector instructions is specified by vectorize_width() and the number of
+/// interleaved loop iterations is specified by interleave_count(). Specifying a
+/// value of 1 effectively disables vectorization/interleaving, even if it is
+/// possible and profitable, and 0 is invalid. The loop vectorizer currently
+/// only works on inner loops.
+///
+void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
+ PragmaIntroducerKind Introducer,
+ Token &Tok) {
+ Token Loop = Tok;
+ SmallVector<Token, 1> TokenList;
+
+ // Lex the optimization option and verify it is an identifier.
+ PP.Lex(Tok);
+ if (Tok.isNot(tok::identifier)) {
+ PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
+ << /*MissingOption=*/true << "";
+ return;
+ }
+
+ while (Tok.is(tok::identifier)) {
+ Token Option = Tok;
+ IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
+
+ if (!OptionInfo->isStr("vectorize") && !OptionInfo->isStr("interleave") &&
+ !OptionInfo->isStr("vectorize_width") &&
+ !OptionInfo->isStr("interleave_count")) {
+ PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
+ << /*MissingOption=*/false << OptionInfo;
+ return;
+ }
+
+ // Read '('
+ PP.Lex(Tok);
+ if (Tok.isNot(tok::l_paren)) {
+ PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
+ return;
+ }
+
+ // FIXME: All tokens between '(' and ')' should be stored and parsed as a
+ // constant expression.
+ PP.Lex(Tok);
+ Token Value;
+ if (Tok.is(tok::identifier) || Tok.is(tok::numeric_constant))
+ Value = Tok;
+
+ // Read ')'
+ PP.Lex(Tok);
+ if (Tok.isNot(tok::r_paren)) {
+ PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
+ return;
+ }
+
+ // Get next optimization option.
+ PP.Lex(Tok);
+
+ auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
+ Info->Loop = Loop;
+ Info->Option = Option;
+ Info->Value = Value;
+
+ // Generate the vectorization hint token.
+ Token LoopHintTok;
+ LoopHintTok.startToken();
+ LoopHintTok.setKind(tok::annot_pragma_loop_hint);
+ LoopHintTok.setLocation(Loop.getLocation());
+ LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
+ TokenList.push_back(LoopHintTok);
+ }
+
+ if (Tok.isNot(tok::eod)) {
+ PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+ << "clang loop";
+ return;
+ }
+
+ Token *TokenArray = new Token[TokenList.size()];
+ std::copy(TokenList.begin(), TokenList.end(), TokenArray);
+
+ PP.EnterTokenStream(TokenArray, TokenList.size(),
+ /*DisableMacroExpansion=*/false,
+ /*OwnsTokens=*/true);
+}
#include "clang/Sema/SemaInternal.h"
#include "clang/AST/ASTContext.h"
-#include "clang/Basic/SourceManager.h"\r
-#include "clang/Sema/DelayedDiagnostic.h"\r
-#include "clang/Sema/Lookup.h"\r
-#include "clang/Sema/LoopHint.h"\r
-#include "clang/Sema/ScopeInfo.h"\r
-#include "llvm/ADT/StringExtras.h"\r
-\r
+#include "clang/Basic/SourceManager.h"
+#include "clang/Sema/DelayedDiagnostic.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/LoopHint.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "llvm/ADT/StringExtras.h"
+
using namespace clang;
using namespace sema;
return nullptr;
}
return ::new (S.Context) FallThroughAttr(A.getRange(), S.Context,
- A.getAttributeSpellingListIndex());\r
-}\r
-\r
-static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,\r
- SourceRange) {\r
- if (St->getStmtClass() != Stmt::DoStmtClass &&\r
- St->getStmtClass() != Stmt::ForStmtClass &&\r
- St->getStmtClass() != Stmt::CXXForRangeStmtClass &&\r
- St->getStmtClass() != Stmt::WhileStmtClass) {\r
- S.Diag(St->getLocStart(), diag::err_pragma_loop_precedes_nonloop);\r
- return nullptr;\r
- }\r
-\r
- IdentifierLoc *OptionLoc = A.getArgAsIdent(0);\r
- IdentifierInfo *OptionInfo = OptionLoc->Ident;\r
- IdentifierLoc *ValueLoc = A.getArgAsIdent(1);\r
- IdentifierInfo *ValueInfo = ValueLoc->Ident;\r
- Expr *ValueExpr = A.getArgAsExpr(2);\r
-\r
- assert(OptionInfo && "Attribute must have valid option info.");\r
-\r
- LoopHintAttr::OptionType Option =\r
- llvm::StringSwitch<LoopHintAttr::OptionType>(OptionInfo->getNameStart())\r
- .Case("vectorize", LoopHintAttr::Vectorize)\r
- .Case("vectorize_width", LoopHintAttr::VectorizeWidth)\r
- .Case("interleave", LoopHintAttr::Interleave)\r
- .Case("interleave_count", LoopHintAttr::InterleaveCount)\r
- .Default(LoopHintAttr::Vectorize);\r
-\r
- int ValueInt;\r
- if (Option == LoopHintAttr::Vectorize || Option == LoopHintAttr::Interleave) {\r
- if (!ValueInfo) {\r
- S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword)\r
- << /*MissingKeyword=*/true << "";\r
- return nullptr;\r
- }\r
-\r
- if (ValueInfo->isStr("disable"))\r
- ValueInt = 0;\r
- else if (ValueInfo->isStr("enable"))\r
- ValueInt = 1;\r
- else {\r
- S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword)\r
- << /*MissingKeyword=*/false << ValueInfo;\r
- return nullptr;\r
- }\r
- } else if (Option == LoopHintAttr::VectorizeWidth ||\r
- Option == LoopHintAttr::InterleaveCount) {\r
- // FIXME: We should support template parameters for the loop hint value.\r
- // See bug report #19610.\r
- llvm::APSInt ValueAPS;\r
- if (!ValueExpr || !ValueExpr->isIntegerConstantExpr(ValueAPS, S.Context)) {\r
- S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_value)\r
- << /*MissingValue=*/true << "";\r
- return nullptr;\r
- }\r
-\r
- if ((ValueInt = ValueAPS.getSExtValue()) < 1) {\r
- S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_value)\r
- << /*MissingValue=*/false << ValueInt;\r
- return nullptr;\r
- }\r
- } else\r
- llvm_unreachable("Unknown loop hint option");\r
-\r
- return LoopHintAttr::CreateImplicit(S.Context, Option, ValueInt,\r
- A.getRange());\r
-}\r
-\r
-static void\r
-CheckForIncompatibleAttributes(Sema &S, SmallVectorImpl<const Attr *> &Attrs) {\r
- int PrevOptionValue[4] = {-1, -1, -1, -1};\r
- int OptionId[4] = {LoopHintAttr::Vectorize, LoopHintAttr::VectorizeWidth,\r
- LoopHintAttr::Interleave, LoopHintAttr::InterleaveCount};\r
-\r
- for (const auto *I : Attrs) {\r
- const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I);\r
-\r
- // Skip non loop hint attributes\r
- if (!LH)\r
- continue;\r
-\r
- int State, Value;\r
- int Option = LH->getOption();\r
- int ValueInt = LH->getValue();\r
-\r
- switch (Option) {\r
- case LoopHintAttr::Vectorize:\r
- case LoopHintAttr::VectorizeWidth:\r
- State = 0;\r
- Value = 1;\r
- break;\r
- case LoopHintAttr::Interleave:\r
- case LoopHintAttr::InterleaveCount:\r
- State = 2;\r
- Value = 3;\r
- break;\r
- }\r
-\r
- SourceLocation ValueLoc = LH->getRange().getEnd();\r
-\r
- // Compatibility testing is split into two cases.\r
- // 1. if the current loop hint sets state (enable/disable) - check against\r
- // previous state and value.\r
- // 2. if the current loop hint sets a value - check against previous state\r
- // and value.\r
-\r
- if (Option == State) {\r
- if (PrevOptionValue[State] != -1) {\r
- // Cannot specify state twice.\r
- int PrevValue = PrevOptionValue[State];\r
- S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)\r
- << /*Duplicate=*/true << LoopHintAttr::getOptionName(Option)\r
- << LoopHintAttr::getValueName(PrevValue)\r
- << LoopHintAttr::getOptionName(Option)\r
- << LoopHintAttr::getValueName(Value);\r
- }\r
-\r
- if (PrevOptionValue[Value] != -1) {\r
- // Compare state with previous width/count.\r
- int PrevOption = OptionId[Value];\r
- int PrevValueInt = PrevOptionValue[Value];\r
- if ((ValueInt == 0 && PrevValueInt > 1) ||\r
- (ValueInt == 1 && PrevValueInt <= 1))\r
- S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)\r
- << /*Duplicate=*/false << LoopHintAttr::getOptionName(PrevOption)\r
- << PrevValueInt << LoopHintAttr::getOptionName(Option)\r
- << LoopHintAttr::getValueName(ValueInt);\r
- }\r
- } else {\r
- if (PrevOptionValue[State] != -1) {\r
- // Compare width/count value with previous state.\r
- int PrevOption = OptionId[State];\r
- int PrevValueInt = PrevOptionValue[State];\r
- if ((ValueInt > 1 && PrevValueInt == 0) ||\r
- (ValueInt <= 1 && PrevValueInt == 1))\r
- S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)\r
- << /*Duplicate=*/false << LoopHintAttr::getOptionName(PrevOption)\r
- << LoopHintAttr::getValueName(PrevValueInt)\r
- << LoopHintAttr::getOptionName(Option) << ValueInt;\r
- }\r
-\r
- if (PrevOptionValue[Value] != -1) {\r
- // Cannot specify a width/count twice.\r
- int PrevValueInt = PrevOptionValue[Value];\r
- S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)\r
- << /*Duplicate=*/true << LoopHintAttr::getOptionName(Option)\r
- << PrevValueInt << LoopHintAttr::getOptionName(Option) << ValueInt;\r
- }\r
- }\r
-\r
- PrevOptionValue[Option] = ValueInt;\r
- }\r
-}\r
-\r
-static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A,\r
- SourceRange Range) {\r
- switch (A.getKind()) {\r
+ A.getAttributeSpellingListIndex());
+}
+
+static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
+ SourceRange) {
+ if (St->getStmtClass() != Stmt::DoStmtClass &&
+ St->getStmtClass() != Stmt::ForStmtClass &&
+ St->getStmtClass() != Stmt::CXXForRangeStmtClass &&
+ St->getStmtClass() != Stmt::WhileStmtClass) {
+ S.Diag(St->getLocStart(), diag::err_pragma_loop_precedes_nonloop);
+ return nullptr;
+ }
+
+ IdentifierLoc *OptionLoc = A.getArgAsIdent(0);
+ IdentifierInfo *OptionInfo = OptionLoc->Ident;
+ IdentifierLoc *ValueLoc = A.getArgAsIdent(1);
+ IdentifierInfo *ValueInfo = ValueLoc->Ident;
+ Expr *ValueExpr = A.getArgAsExpr(2);
+
+ assert(OptionInfo && "Attribute must have valid option info.");
+
+ LoopHintAttr::OptionType Option =
+ llvm::StringSwitch<LoopHintAttr::OptionType>(OptionInfo->getNameStart())
+ .Case("vectorize", LoopHintAttr::Vectorize)
+ .Case("vectorize_width", LoopHintAttr::VectorizeWidth)
+ .Case("interleave", LoopHintAttr::Interleave)
+ .Case("interleave_count", LoopHintAttr::InterleaveCount)
+ .Default(LoopHintAttr::Vectorize);
+
+ int ValueInt;
+ if (Option == LoopHintAttr::Vectorize || Option == LoopHintAttr::Interleave) {
+ if (!ValueInfo) {
+ S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword)
+ << /*MissingKeyword=*/true << "";
+ return nullptr;
+ }
+
+ if (ValueInfo->isStr("disable"))
+ ValueInt = 0;
+ else if (ValueInfo->isStr("enable"))
+ ValueInt = 1;
+ else {
+ S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword)
+ << /*MissingKeyword=*/false << ValueInfo;
+ return nullptr;
+ }
+ } else if (Option == LoopHintAttr::VectorizeWidth ||
+ Option == LoopHintAttr::InterleaveCount) {
+ // FIXME: We should support template parameters for the loop hint value.
+ // See bug report #19610.
+ llvm::APSInt ValueAPS;
+ if (!ValueExpr || !ValueExpr->isIntegerConstantExpr(ValueAPS, S.Context)) {
+ S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_value)
+ << /*MissingValue=*/true << "";
+ return nullptr;
+ }
+
+ if ((ValueInt = ValueAPS.getSExtValue()) < 1) {
+ S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_value)
+ << /*MissingValue=*/false << ValueInt;
+ return nullptr;
+ }
+ } else
+ llvm_unreachable("Unknown loop hint option");
+
+ return LoopHintAttr::CreateImplicit(S.Context, Option, ValueInt,
+ A.getRange());
+}
+
+static void
+CheckForIncompatibleAttributes(Sema &S, SmallVectorImpl<const Attr *> &Attrs) {
+ int PrevOptionValue[4] = {-1, -1, -1, -1};
+ int OptionId[4] = {LoopHintAttr::Vectorize, LoopHintAttr::VectorizeWidth,
+ LoopHintAttr::Interleave, LoopHintAttr::InterleaveCount};
+
+ for (const auto *I : Attrs) {
+ const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I);
+
+ // Skip non loop hint attributes
+ if (!LH)
+ continue;
+
+ int State, Value;
+ int Option = LH->getOption();
+ int ValueInt = LH->getValue();
+
+ switch (Option) {
+ case LoopHintAttr::Vectorize:
+ case LoopHintAttr::VectorizeWidth:
+ State = 0;
+ Value = 1;
+ break;
+ case LoopHintAttr::Interleave:
+ case LoopHintAttr::InterleaveCount:
+ State = 2;
+ Value = 3;
+ break;
+ }
+
+ SourceLocation ValueLoc = LH->getRange().getEnd();
+
+ // Compatibility testing is split into two cases.
+ // 1. if the current loop hint sets state (enable/disable) - check against
+ // previous state and value.
+ // 2. if the current loop hint sets a value - check against previous state
+ // and value.
+
+ if (Option == State) {
+ if (PrevOptionValue[State] != -1) {
+ // Cannot specify state twice.
+ int PrevValue = PrevOptionValue[State];
+ S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
+ << /*Duplicate=*/true << LoopHintAttr::getOptionName(Option)
+ << LoopHintAttr::getValueName(PrevValue)
+ << LoopHintAttr::getOptionName(Option)
+ << LoopHintAttr::getValueName(Value);
+ }
+
+ if (PrevOptionValue[Value] != -1) {
+ // Compare state with previous width/count.
+ int PrevOption = OptionId[Value];
+ int PrevValueInt = PrevOptionValue[Value];
+ if ((ValueInt == 0 && PrevValueInt > 1) ||
+ (ValueInt == 1 && PrevValueInt <= 1))
+ S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
+ << /*Duplicate=*/false << LoopHintAttr::getOptionName(PrevOption)
+ << PrevValueInt << LoopHintAttr::getOptionName(Option)
+ << LoopHintAttr::getValueName(ValueInt);
+ }
+ } else {
+ if (PrevOptionValue[State] != -1) {
+ // Compare width/count value with previous state.
+ int PrevOption = OptionId[State];
+ int PrevValueInt = PrevOptionValue[State];
+ if ((ValueInt > 1 && PrevValueInt == 0) ||
+ (ValueInt <= 1 && PrevValueInt == 1))
+ S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
+ << /*Duplicate=*/false << LoopHintAttr::getOptionName(PrevOption)
+ << LoopHintAttr::getValueName(PrevValueInt)
+ << LoopHintAttr::getOptionName(Option) << ValueInt;
+ }
+
+ if (PrevOptionValue[Value] != -1) {
+ // Cannot specify a width/count twice.
+ int PrevValueInt = PrevOptionValue[Value];
+ S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
+ << /*Duplicate=*/true << LoopHintAttr::getOptionName(Option)
+ << PrevValueInt << LoopHintAttr::getOptionName(Option) << ValueInt;
+ }
+ }
+
+ PrevOptionValue[Option] = ValueInt;
+ }
+}
+
+static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A,
+ SourceRange Range) {
+ switch (A.getKind()) {
case AttributeList::UnknownAttribute:
S.Diag(A.getLoc(), A.isDeclspecAttribute() ?
diag::warn_unhandled_ms_attribute_ignored :
diag::warn_unknown_attribute_ignored) << A.getName();
- return nullptr;\r
- case AttributeList::AT_FallThrough:\r
- return handleFallThroughAttr(S, St, A, Range);\r
- case AttributeList::AT_LoopHint:\r
- return handleLoopHintAttr(S, St, A, Range);\r
- default:\r
- // if we're here, then we parsed a known attribute, but didn't recognize\r
- // it as a statement attribute => it is declaration attribute\r
+ return nullptr;
+ case AttributeList::AT_FallThrough:
+ return handleFallThroughAttr(S, St, A, Range);
+ case AttributeList::AT_LoopHint:
+ return handleLoopHintAttr(S, St, A, Range);
+ default:
+ // if we're here, then we parsed a known attribute, but didn't recognize
+ // it as a statement attribute => it is declaration attribute
S.Diag(A.getRange().getBegin(), diag::err_attribute_invalid_on_stmt)
<< A.getName() << St->getLocStart();
return nullptr;
SmallVector<const Attr*, 8> Attrs;
for (const AttributeList* l = AttrList; l; l = l->getNext()) {
if (Attr *a = ProcessStmtAttribute(*this, S, *l, Range))
- Attrs.push_back(a);\r
- }\r
-\r
- CheckForIncompatibleAttributes(*this, Attrs);\r
-\r
- if (Attrs.empty())\r
- return S;\r
-\r
+ Attrs.push_back(a);
+ }
+
+ CheckForIncompatibleAttributes(*this, Attrs);
+
+ if (Attrs.empty())
+ return S;
+
return ActOnAttributedStmt(Range.getBegin(), Attrs, S);
}
// Shouldn't crash.
namespace Test8 {
- struct A {};\r
- struct D { int a; };\r
- struct B : virtual D, A { };\r
- struct C : B, A { void f() {} };\r
- C c;\r
+ struct A {};
+ struct D { int a; };
+ struct B : virtual D, A { };
+ struct C : B, A { void f() {} };
+ C c;
}