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);
}
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,
// 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;
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 += ',';
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