summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Nowicki <tnowicki@apple.com>2014-07-29 17:21:32 +0000
committerTyler Nowicki <tnowicki@apple.com>2014-07-29 17:21:32 +0000
commit93c915721ece64f52c95121318724c5c251d7467 (patch)
tree0d7a2c6f3cb04499667852462414a8143b29661f
parentfa3d66d724a1d7db2c096e1fbbebf7b9b5fd7bb5 (diff)
downloadclang-93c915721ece64f52c95121318724c5c251d7467.tar.gz
Modify how the loop hint attribute is printed as a lead-up to supporting constant expression values.
Reviewed by Aaron Ballman git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@214185 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/Attr.td58
-rw-r--r--lib/Sema/SemaStmtAttr.cpp16
2 files changed, 31 insertions, 43 deletions
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 0af6f97504..b914faf6b1 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -1803,7 +1803,7 @@ def LoopHint : Attr {
DefaultIntArgument<"Value", 1>];
let AdditionalMembers = [{
- static StringRef getOptionName(int Option) {
+ static const char *getOptionName(int Option) {
switch(Option) {
case Vectorize: return "vectorize";
case VectorizeWidth: return "vectorize_width";
@@ -1815,12 +1815,6 @@ def LoopHint : Attr {
llvm_unreachable("Unhandled LoopHint option.");
}
- static StringRef getValueName(int Value) {
- if (Value)
- return "enable";
- return "disable";
- }
-
void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
unsigned SpellingIndex = getSpellingListIndex();
// For "#pragma unroll" and "#pragma nounroll" the string "unroll" or
@@ -1829,52 +1823,44 @@ def LoopHint : Attr {
OS << "\n";
return;
}
- if (SpellingIndex == Pragma_unroll) {
- if (option == UnrollCount)
- printArgument(OS);
- OS << "\n";
+ else if (SpellingIndex == Pragma_unroll) {
+ OS << getValueString(Policy) << "\n";
return;
}
+
assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
- OS << getOptionName(option);
- printArgument(OS);
- OS << "\n";
+ OS << getOptionName(option) << getValueString(Policy) << "\n";
}
- // Prints the loop hint argument including the enclosing parentheses to OS.
- void printArgument(raw_ostream &OS) const {
+ // Return a string containing the loop hint argument including the
+ // enclosing parentheses.
+ std::string getValueString(const PrintingPolicy &Policy) const {
+ std::string ValueName;
+ llvm::raw_string_ostream OS(ValueName);
OS << "(";
if (option == VectorizeWidth || option == InterleaveCount ||
option == UnrollCount)
OS << value;
- else if (option == Unroll && value)
- // Unroll loop hint does not use the keyword "enable". Instead, a nonzero value
- // indicates full unrolling which uses the keyword "full".
- OS << "full";
- else if (value)
- OS << "enable";
+ else if (value < 0)
+ return "";
+ else if (value > 0)
+ OS << (option == Unroll ? "full" : "enable");
else
OS << "disable";
OS << ")";
+ return OS.str();
}
// Return a string suitable for identifying this attribute in diagnostics.
- std::string getDiagnosticName() const {
- std::string DiagnosticName;
- llvm::raw_string_ostream OS(DiagnosticName);
+ std::string getDiagnosticName(const PrintingPolicy &Policy) const {
unsigned SpellingIndex = getSpellingListIndex();
if (SpellingIndex == Pragma_nounroll)
- OS << "#pragma nounroll";
- else if (SpellingIndex == Pragma_unroll) {
- OS << "#pragma unroll";
- if (option == UnrollCount)
- printArgument(OS);
- } else {
- assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
- OS << getOptionName(option);
- printArgument(OS);
- }
- return OS.str();
+ return "#pragma nounroll";
+ else if (SpellingIndex == Pragma_unroll)
+ return "#pragma unroll" + getValueString(Policy);
+
+ assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
+ return getOptionName(option) + getValueString(Policy);
}
}];
diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp
index 86c487b4cd..595aa3656e 100644
--- a/lib/Sema/SemaStmtAttr.cpp
+++ b/lib/Sema/SemaStmtAttr.cpp
@@ -87,10 +87,11 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
Spelling = LoopHintAttr::Pragma_clang_loop;
}
- int ValueInt;
+ int ValueInt = -1;
if (Option == LoopHintAttr::Unroll &&
Spelling == LoopHintAttr::Pragma_unroll) {
- ValueInt = 1;
+ if (ValueInfo)
+ ValueInt = (ValueInfo->isStr("disable") ? 0 : 1);
} else if (Option == LoopHintAttr::Unroll &&
Spelling == LoopHintAttr::Pragma_nounroll) {
ValueInt = 0;
@@ -174,7 +175,6 @@ static void CheckForIncompatibleAttributes(
};
auto &CategoryState = HintAttrs[Category];
- SourceLocation OptionLoc = LH->getRange().getBegin();
const LoopHintAttr *PrevAttr;
if (Option == LoopHintAttr::Vectorize ||
Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll) {
@@ -187,11 +187,13 @@ static void CheckForIncompatibleAttributes(
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()
- << LH->getDiagnosticName();
+ << /*Duplicate=*/true << PrevAttr->getDiagnosticName(Policy)
+ << LH->getDiagnosticName(Policy);
if (CategoryState.EnableAttr && CategoryState.NumericAttr &&
(Category == Unroll || !CategoryState.EnableAttr->getValue())) {
@@ -200,8 +202,8 @@ static void CheckForIncompatibleAttributes(
// compatible with "enable" form of the unroll pragma, unroll(full).
S.Diag(OptionLoc, diag::err_pragma_loop_compatibility)
<< /*Duplicate=*/false
- << CategoryState.EnableAttr->getDiagnosticName()
- << CategoryState.NumericAttr->getDiagnosticName();
+ << CategoryState.EnableAttr->getDiagnosticName(Policy)
+ << CategoryState.NumericAttr->getDiagnosticName(Policy);
}
}
}