// NOTE: when memoizing the function type, we have to be careful to handle the
// case when the type gets refined.
// NOTE: when memoizing the function type, we have to be careful to handle the
// case when the type gets refined.
-InlineAsm *InlineAsm::get(const FunctionType *Ty, const std::string &AsmString,
- const std::string &Constraints, bool hasSideEffects) {
+InlineAsm *InlineAsm::get(const FunctionType *Ty, const StringRef &AsmString,
+ const StringRef &Constraints, bool hasSideEffects,
+ bool isMsAsm) {
- return new InlineAsm(Ty, AsmString, Constraints, hasSideEffects);
+ return new InlineAsm(Ty, AsmString, Constraints, hasSideEffects, isMsAsm);
-InlineAsm::InlineAsm(const FunctionType *Ty, const std::string &asmString,
- const std::string &constraints, bool hasSideEffects)
+InlineAsm::InlineAsm(const FunctionType *Ty, const StringRef &asmString,
+ const StringRef &constraints, bool hasSideEffects,
+ bool isMsAsm)
// Do various checks on the constraint string and type.
assert(Verify(Ty, constraints) && "Function type not legal for constraints!");
// Do various checks on the constraint string and type.
assert(Verify(Ty, constraints) && "Function type not legal for constraints!");
/// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the
/// fields in this structure. If the constraint string is not understood,
/// return true, otherwise return false.
/// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the
/// fields in this structure. If the constraint string is not understood,
/// return true, otherwise return false.
if (ConstraintEnd == E) return true; // "{foo"
Codes.push_back(std::string(I, ConstraintEnd+1));
I = ConstraintEnd+1;
} else if (isdigit(*I)) { // Matching Constraint
// Maximal munch numbers.
if (ConstraintEnd == E) return true; // "{foo"
Codes.push_back(std::string(I, ConstraintEnd+1));
I = ConstraintEnd+1;
} else if (isdigit(*I)) { // Matching Constraint
// Maximal munch numbers.
while (I != E && isdigit(*I))
++I;
Codes.push_back(std::string(NumStart, I));
while (I != E && isdigit(*I))
++I;
Codes.push_back(std::string(NumStart, I));
} else {
// Single letter constraint.
Codes.push_back(std::string(I, I+1));
} else {
// Single letter constraint.
Codes.push_back(std::string(I, I+1));
- for (std::string::const_iterator I = Constraints.begin(),
- E = Constraints.end(); I != E; ) {
+ for (StringRef::iterator I = Constraints.begin(),
+ E = Constraints.end(); I != E; ) {
- std::string::const_iterator ConstraintEnd = std::find(I, E, ',');
+ StringRef::iterator ConstraintEnd = std::find(I, E, ',');
if (ConstraintEnd == I || // Empty constraint like ",,"
Info.Parse(std::string(I, ConstraintEnd), Result)) {
if (ConstraintEnd == I || // Empty constraint like ",,"
Info.Parse(std::string(I, ConstraintEnd), Result)) {
/// Verify - Verify that the specified constraint string is reasonable for the
/// specified function type, and otherwise validate the constraint string.
/// Verify - Verify that the specified constraint string is reasonable for the
/// specified function type, and otherwise validate the constraint string.
if (Ty->isVarArg()) return false;
std::vector<ConstraintInfo> Constraints = ParseConstraints(ConstStr);
if (Ty->isVarArg()) return false;
std::vector<ConstraintInfo> Constraints = ParseConstraints(ConstStr);
if (Constraints.empty() && !ConstStr.empty()) return false;
unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0;
if (Constraints.empty() && !ConstStr.empty()) return false;
unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0;
for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
switch (Constraints[i].Type) {
case InlineAsm::isOutput:
for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
switch (Constraints[i].Type) {
case InlineAsm::isOutput:
- if ((Ty->getReturnType() != Type::VoidTy) != NumOutputs)
- return false; // NumOutputs = 1 iff has a result type.
+ switch (NumOutputs) {
+ case 0:
+ if (Ty->getReturnType() != Type::getVoidTy(Ty->getContext())) return false;
+ break;
+ case 1:
+ if (isa<StructType>(Ty->getReturnType())) return false;
+ break;
+ default:
+ const StructType *STy = dyn_cast<StructType>(Ty->getReturnType());
+ if (STy == 0 || STy->getNumElements() != NumOutputs)
+ return false;
+ break;
+ }