Add sema support for symbolic names in inline asm statements.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62441 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index ca755b9..da14365 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -202,7 +202,11 @@
const std::string *OutputNamesBegin,
const std::string *OutputNamesEnd,
ConstraintInfo &info) const;
-
+ bool resolveSymbolicName(const char *&Name,
+ const std::string *OutputNamesBegin,
+ const std::string *OutputNamesEnd,
+ unsigned &Index) const;
+
virtual std::string convertConstraint(const char Constraint) const {
return std::string(1, Constraint);
}
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index 2ea1f23..eb912d5 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/lib/Basic/TargetInfo.cpp
@@ -188,6 +188,36 @@
return true;
}
+bool TargetInfo::resolveSymbolicName(const char *&Name,
+ const std::string *OutputNamesBegin,
+ const std::string *OutputNamesEnd,
+ unsigned &Index) const
+{
+ assert(*Name == '[' && "Symbolic name did not start with '['");
+
+ Name++;
+ const char *Start = Name;
+ while (*Name && *Name != ']')
+ Name++;
+
+ if (!*Name) {
+ // Missing ']'
+ return false;
+ }
+
+ std::string SymbolicName(Start, Name - Start);
+
+ Index = 0;
+ for (const std::string *it = OutputNamesBegin;
+ it != OutputNamesEnd;
+ ++it, Index++) {
+ if (SymbolicName == *it)
+ return true;
+ }
+
+ return false;
+}
+
bool TargetInfo::validateInputConstraint(const char *Name,
const std::string *OutputNamesBegin,
const std::string *OutputNamesEnd,
@@ -210,7 +240,15 @@
// add more constraints as we hit it. Eventually, an unknown
// constraint should just be treated as 'g'.
return false;
- }
+ }
+ break;
+ case '[': {
+ unsigned Index = 0;
+ if (!resolveSymbolicName(Name, OutputNamesBegin, OutputNamesEnd, Index))
+ return false;
+
+ break;
+ }
case '%': // commutative
// FIXME: Fail if % is used with the last operand.
break;
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index d86c3f4..04fc26d 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -980,7 +980,7 @@
S.begin_output_names(),
S.end_output_names(),
Info);
- assert(result && "Failed to parse input constraint"); result=result;
+ assert(result && "Failed to parse input constraint");
if (i != 0 || S.getNumOutputs() > 0)
Constraints += ',';
diff --git a/test/Sema/asm.c b/test/Sema/asm.c
index d29335a..3bb7d78 100644
--- a/test/Sema/asm.c
+++ b/test/Sema/asm.c
@@ -10,7 +10,11 @@
asm ("foo\n" : "=a" (f())); // expected-error {{invalid lvalue in asm output}}
asm ("foo\n" : "=a" (i + 2)); // expected-error {{invalid lvalue in asm output}}
-
+
+ asm ("foo\n" : [symbolic_name] "=a" (i) : "[symbolic_name]" (i));
+ asm ("foo\n" : "=a" (i) : "[" (i)); // expected-error {{invalid input constraint '[' in asm}}
+ asm ("foo\n" : "=a" (i) : "[foo" (i)); // expected-error {{invalid input constraint '[foo' in asm}}
+ asm ("foo\n" : "=a" (i) : "[symbolic_name]" (i)); // expected-error {{invalid input constraint '[symbolic_name]' in asm}}
}
void