diff options
| author | 2020-08-03 15:06:44 +0000 | |
|---|---|---|
| committer | 2020-08-03 15:06:44 +0000 | |
| commit | b64793999546ed8adebaeebd9d8345d18db8927d (patch) | |
| tree | 4357c27b561d73b0e089727c6ed659f2ceff5f47 /gnu/llvm/tools/clang/lib/Sema/SemaStmtAttr.cpp | |
| parent | Add support for UTF-8 DISPLAY-HINTs with octet length. For now only (diff) | |
| download | wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.tar.xz wireguard-openbsd-b64793999546ed8adebaeebd9d8345d18db8927d.zip | |
Remove LLVM 8.0.1 files.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Sema/SemaStmtAttr.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Sema/SemaStmtAttr.cpp | 370 |
1 files changed, 0 insertions, 370 deletions
diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaStmtAttr.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaStmtAttr.cpp deleted file mode 100644 index a8e54b36b29..00000000000 --- a/gnu/llvm/tools/clang/lib/Sema/SemaStmtAttr.cpp +++ /dev/null @@ -1,370 +0,0 @@ -//===--- SemaStmtAttr.cpp - Statement Attribute Handling ------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements stmt-related attribute processing. -// -//===----------------------------------------------------------------------===// - -#include "clang/Sema/SemaInternal.h" -#include "clang/AST/ASTContext.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Sema/DelayedDiagnostic.h" -#include "clang/Sema/Lookup.h" -#include "clang/Sema/ScopeInfo.h" -#include "llvm/ADT/StringExtras.h" - -using namespace clang; -using namespace sema; - -static Attr *handleFallThroughAttr(Sema &S, Stmt *St, const ParsedAttr &A, - SourceRange Range) { - FallThroughAttr Attr(A.getRange(), S.Context, - A.getAttributeSpellingListIndex()); - if (!isa<NullStmt>(St)) { - S.Diag(A.getRange().getBegin(), diag::err_fallthrough_attr_wrong_target) - << Attr.getSpelling() << St->getBeginLoc(); - if (isa<SwitchCase>(St)) { - SourceLocation L = S.getLocForEndOfToken(Range.getEnd()); - S.Diag(L, diag::note_fallthrough_insert_semi_fixit) - << FixItHint::CreateInsertion(L, ";"); - } - return nullptr; - } - auto *FnScope = S.getCurFunction(); - if (FnScope->SwitchStack.empty()) { - S.Diag(A.getRange().getBegin(), diag::err_fallthrough_attr_outside_switch); - return nullptr; - } - - // If this is spelled as the standard C++17 attribute, but not in C++17, warn - // about using it as an extension. - if (!S.getLangOpts().CPlusPlus17 && A.isCXX11Attribute() && - !A.getScopeName()) - S.Diag(A.getLoc(), diag::ext_cxx17_attr) << A.getName(); - - FnScope->setHasFallthroughStmt(); - return ::new (S.Context) auto(Attr); -} - -static Attr *handleSuppressAttr(Sema &S, Stmt *St, const ParsedAttr &A, - SourceRange Range) { - if (A.getNumArgs() < 1) { - S.Diag(A.getLoc(), diag::err_attribute_too_few_arguments) << A << 1; - return nullptr; - } - - std::vector<StringRef> DiagnosticIdentifiers; - for (unsigned I = 0, E = A.getNumArgs(); I != E; ++I) { - StringRef RuleName; - - if (!S.checkStringLiteralArgumentAttr(A, I, RuleName, nullptr)) - return nullptr; - - // FIXME: Warn if the rule name is unknown. This is tricky because only - // clang-tidy knows about available rules. - DiagnosticIdentifiers.push_back(RuleName); - } - - return ::new (S.Context) SuppressAttr( - A.getRange(), S.Context, DiagnosticIdentifiers.data(), - DiagnosticIdentifiers.size(), A.getAttributeSpellingListIndex()); -} - -static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A, - SourceRange) { - IdentifierLoc *PragmaNameLoc = A.getArgAsIdent(0); - IdentifierLoc *OptionLoc = A.getArgAsIdent(1); - IdentifierLoc *StateLoc = A.getArgAsIdent(2); - Expr *ValueExpr = A.getArgAsExpr(3); - - bool PragmaUnroll = PragmaNameLoc->Ident->getName() == "unroll"; - bool PragmaNoUnroll = PragmaNameLoc->Ident->getName() == "nounroll"; - bool PragmaUnrollAndJam = PragmaNameLoc->Ident->getName() == "unroll_and_jam"; - bool PragmaNoUnrollAndJam = - PragmaNameLoc->Ident->getName() == "nounroll_and_jam"; - if (St->getStmtClass() != Stmt::DoStmtClass && - St->getStmtClass() != Stmt::ForStmtClass && - St->getStmtClass() != Stmt::CXXForRangeStmtClass && - St->getStmtClass() != Stmt::WhileStmtClass) { - const char *Pragma = - llvm::StringSwitch<const char *>(PragmaNameLoc->Ident->getName()) - .Case("unroll", "#pragma unroll") - .Case("nounroll", "#pragma nounroll") - .Case("unroll_and_jam", "#pragma unroll_and_jam") - .Case("nounroll_and_jam", "#pragma nounroll_and_jam") - .Default("#pragma clang loop"); - S.Diag(St->getBeginLoc(), diag::err_pragma_loop_precedes_nonloop) << Pragma; - return nullptr; - } - - LoopHintAttr::Spelling Spelling = - LoopHintAttr::Spelling(A.getAttributeSpellingListIndex()); - LoopHintAttr::OptionType Option; - LoopHintAttr::LoopHintState State; - if (PragmaNoUnroll) { - // #pragma nounroll - Option = LoopHintAttr::Unroll; - State = LoopHintAttr::Disable; - } else if (PragmaUnroll) { - if (ValueExpr) { - // #pragma unroll N - Option = LoopHintAttr::UnrollCount; - State = LoopHintAttr::Numeric; - } else { - // #pragma unroll - Option = LoopHintAttr::Unroll; - State = LoopHintAttr::Enable; - } - } else if (PragmaNoUnrollAndJam) { - // #pragma nounroll_and_jam - Option = LoopHintAttr::UnrollAndJam; - State = LoopHintAttr::Disable; - } else if (PragmaUnrollAndJam) { - if (ValueExpr) { - // #pragma unroll_and_jam N - Option = LoopHintAttr::UnrollAndJamCount; - State = LoopHintAttr::Numeric; - } else { - // #pragma unroll_and_jam - Option = LoopHintAttr::UnrollAndJam; - State = LoopHintAttr::Enable; - } - } else { - // #pragma clang loop ... - assert(OptionLoc && OptionLoc->Ident && - "Attribute must have valid option info."); - Option = llvm::StringSwitch<LoopHintAttr::OptionType>( - OptionLoc->Ident->getName()) - .Case("vectorize", LoopHintAttr::Vectorize) - .Case("vectorize_width", LoopHintAttr::VectorizeWidth) - .Case("interleave", LoopHintAttr::Interleave) - .Case("interleave_count", LoopHintAttr::InterleaveCount) - .Case("unroll", LoopHintAttr::Unroll) - .Case("unroll_count", LoopHintAttr::UnrollCount) - .Case("pipeline", LoopHintAttr::PipelineDisabled) - .Case("pipeline_initiation_interval", - LoopHintAttr::PipelineInitiationInterval) - .Case("distribute", LoopHintAttr::Distribute) - .Default(LoopHintAttr::Vectorize); - if (Option == LoopHintAttr::VectorizeWidth || - Option == LoopHintAttr::InterleaveCount || - Option == LoopHintAttr::UnrollCount || - Option == LoopHintAttr::PipelineInitiationInterval) { - assert(ValueExpr && "Attribute must have a valid value expression."); - if (S.CheckLoopHintExpr(ValueExpr, St->getBeginLoc())) - return nullptr; - State = LoopHintAttr::Numeric; - } else if (Option == LoopHintAttr::Vectorize || - Option == LoopHintAttr::Interleave || - Option == LoopHintAttr::Unroll || - Option == LoopHintAttr::Distribute || - Option == LoopHintAttr::PipelineDisabled) { - assert(StateLoc && StateLoc->Ident && "Loop hint must have an argument"); - if (StateLoc->Ident->isStr("disable")) - State = LoopHintAttr::Disable; - else if (StateLoc->Ident->isStr("assume_safety")) - State = LoopHintAttr::AssumeSafety; - else if (StateLoc->Ident->isStr("full")) - State = LoopHintAttr::Full; - else if (StateLoc->Ident->isStr("enable")) - State = LoopHintAttr::Enable; - else - llvm_unreachable("bad loop hint argument"); - } else - llvm_unreachable("bad loop hint"); - } - - return LoopHintAttr::CreateImplicit(S.Context, Spelling, Option, State, - ValueExpr, A.getRange()); -} - -static void -CheckForIncompatibleAttributes(Sema &S, - const SmallVectorImpl<const Attr *> &Attrs) { - // There are 6 categories of loop hints attributes: vectorize, interleave, - // unroll, unroll_and_jam, pipeline and distribute. Except for distribute they - // come in two variants: a state form and a numeric form. The state form - // selectively defaults/enables/disables the transformation for the loop - // (for unroll, default indicates full unrolling rather than enabling the - // transformation). The numeric form form provides an integer hint (for - // example, unroll count) to the transformer. The following array accumulates - // the hints encountered while iterating through the attributes to check for - // compatibility. - struct { - const LoopHintAttr *StateAttr; - const LoopHintAttr *NumericAttr; - } HintAttrs[] = {{nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, - {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}}; - - for (const auto *I : Attrs) { - const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I); - - // Skip non loop hint attributes - if (!LH) - continue; - - LoopHintAttr::OptionType Option = LH->getOption(); - enum { - Vectorize, - Interleave, - Unroll, - UnrollAndJam, - Distribute, - Pipeline - } Category; - switch (Option) { - case LoopHintAttr::Vectorize: - case LoopHintAttr::VectorizeWidth: - Category = Vectorize; - break; - case LoopHintAttr::Interleave: - case LoopHintAttr::InterleaveCount: - Category = Interleave; - break; - case LoopHintAttr::Unroll: - case LoopHintAttr::UnrollCount: - Category = Unroll; - break; - case LoopHintAttr::UnrollAndJam: - case LoopHintAttr::UnrollAndJamCount: - Category = UnrollAndJam; - break; - case LoopHintAttr::Distribute: - // Perform the check for duplicated 'distribute' hints. - Category = Distribute; - break; - case LoopHintAttr::PipelineDisabled: - case LoopHintAttr::PipelineInitiationInterval: - Category = Pipeline; - break; - }; - - assert(Category < sizeof(HintAttrs) / sizeof(HintAttrs[0])); - auto &CategoryState = HintAttrs[Category]; - const LoopHintAttr *PrevAttr; - if (Option == LoopHintAttr::Vectorize || - Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll || - Option == LoopHintAttr::UnrollAndJam || - Option == LoopHintAttr::PipelineDisabled || - Option == LoopHintAttr::Distribute) { - // Enable|Disable|AssumeSafety hint. For example, vectorize(enable). - PrevAttr = CategoryState.StateAttr; - CategoryState.StateAttr = LH; - } else { - // Numeric hint. For example, vectorize_width(8). - PrevAttr = CategoryState.NumericAttr; - CategoryState.NumericAttr = LH; - } - - PrintingPolicy Policy(S.Context.getLangOpts()); - SourceLocation OptionLoc = LH->getRange().getBegin(); - if (PrevAttr) - // Cannot specify same type of attribute twice. - S.Diag(OptionLoc, diag::err_pragma_loop_compatibility) - << /*Duplicate=*/true << PrevAttr->getDiagnosticName(Policy) - << LH->getDiagnosticName(Policy); - - if (CategoryState.StateAttr && CategoryState.NumericAttr && - (Category == Unroll || Category == UnrollAndJam || - CategoryState.StateAttr->getState() == LoopHintAttr::Disable)) { - // Disable hints are not compatible with numeric hints of the same - // category. As a special case, numeric unroll hints are also not - // compatible with enable or full form of the unroll pragma because these - // directives indicate full unrolling. - S.Diag(OptionLoc, diag::err_pragma_loop_compatibility) - << /*Duplicate=*/false - << CategoryState.StateAttr->getDiagnosticName(Policy) - << CategoryState.NumericAttr->getDiagnosticName(Policy); - } - } -} - -static Attr *handleOpenCLUnrollHint(Sema &S, Stmt *St, const ParsedAttr &A, - SourceRange Range) { - // Although the feature was introduced only in OpenCL C v2.0 s6.11.5, it's - // useful for OpenCL 1.x too and doesn't require HW support. - // opencl_unroll_hint can have 0 arguments (compiler - // determines unrolling factor) or 1 argument (the unroll factor provided - // by the user). - - unsigned NumArgs = A.getNumArgs(); - - if (NumArgs > 1) { - S.Diag(A.getLoc(), diag::err_attribute_too_many_arguments) << A << 1; - return nullptr; - } - - unsigned UnrollFactor = 0; - - if (NumArgs == 1) { - Expr *E = A.getArgAsExpr(0); - llvm::APSInt ArgVal(32); - - if (!E->isIntegerConstantExpr(ArgVal, S.Context)) { - S.Diag(A.getLoc(), diag::err_attribute_argument_type) - << A << AANT_ArgumentIntegerConstant << E->getSourceRange(); - return nullptr; - } - - int Val = ArgVal.getSExtValue(); - - if (Val <= 0) { - S.Diag(A.getRange().getBegin(), - diag::err_attribute_requires_positive_integer) - << A << /* positive */ 0; - return nullptr; - } - UnrollFactor = Val; - } - - return OpenCLUnrollHintAttr::CreateImplicit(S.Context, UnrollFactor); -} - -static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A, - SourceRange Range) { - switch (A.getKind()) { - case ParsedAttr::UnknownAttribute: - S.Diag(A.getLoc(), A.isDeclspecAttribute() - ? (unsigned)diag::warn_unhandled_ms_attribute_ignored - : (unsigned)diag::warn_unknown_attribute_ignored) - << A.getName(); - return nullptr; - case ParsedAttr::AT_FallThrough: - return handleFallThroughAttr(S, St, A, Range); - case ParsedAttr::AT_LoopHint: - return handleLoopHintAttr(S, St, A, Range); - case ParsedAttr::AT_OpenCLUnrollHint: - return handleOpenCLUnrollHint(S, St, A, Range); - case ParsedAttr::AT_Suppress: - return handleSuppressAttr(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_decl_attribute_invalid_on_stmt) - << A.getName() << St->getBeginLoc(); - return nullptr; - } -} - -StmtResult Sema::ProcessStmtAttributes(Stmt *S, - const ParsedAttributesView &AttrList, - SourceRange Range) { - SmallVector<const Attr*, 8> Attrs; - for (const ParsedAttr &AL : AttrList) { - if (Attr *a = ProcessStmtAttribute(*this, S, AL, Range)) - Attrs.push_back(a); - } - - CheckForIncompatibleAttributes(*this, Attrs); - - if (Attrs.empty()) - return S; - - return ActOnAttributedStmt(Range.getBegin(), Attrs, S); -} |
