|
@@ -262,10 +262,15 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
|
OutputName = Names[i]->getName();
|
|
OutputName = Names[i]->getName();
|
|
|
|
|
|
TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName);
|
|
TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName);
|
|
- if (!Context.getTargetInfo().validateOutputConstraint(Info))
|
|
|
|
- return StmtResult(targetDiag(Literal->getBeginLoc(),
|
|
|
|
- diag::err_asm_invalid_output_constraint)
|
|
|
|
- << Info.getConstraintStr());
|
|
|
|
|
|
+ if (!Context.getTargetInfo().validateOutputConstraint(Info)) {
|
|
|
|
+ targetDiag(Literal->getBeginLoc(),
|
|
|
|
+ diag::err_asm_invalid_output_constraint)
|
|
|
|
+ << Info.getConstraintStr();
|
|
|
|
+ return new (Context)
|
|
|
|
+ GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs,
|
|
|
|
+ NumInputs, Names, Constraints, Exprs.data(), AsmString,
|
|
|
|
+ NumClobbers, Clobbers, RParenLoc);
|
|
|
|
+ }
|
|
|
|
|
|
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
|
|
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
|
|
if (ER.isInvalid())
|
|
if (ER.isInvalid())
|
|
@@ -318,10 +323,15 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
|
}
|
|
}
|
|
|
|
|
|
unsigned Size = Context.getTypeSize(OutputExpr->getType());
|
|
unsigned Size = Context.getTypeSize(OutputExpr->getType());
|
|
- if (!Context.getTargetInfo().validateOutputSize(Literal->getString(), Size))
|
|
|
|
- return StmtResult(targetDiag(OutputExpr->getBeginLoc(),
|
|
|
|
- diag::err_asm_invalid_output_size)
|
|
|
|
- << Info.getConstraintStr());
|
|
|
|
|
|
+ if (!Context.getTargetInfo().validateOutputSize(Literal->getString(),
|
|
|
|
+ Size)) {
|
|
|
|
+ targetDiag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_output_size)
|
|
|
|
+ << Info.getConstraintStr();
|
|
|
|
+ return new (Context)
|
|
|
|
+ GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs,
|
|
|
|
+ NumInputs, Names, Constraints, Exprs.data(), AsmString,
|
|
|
|
+ NumClobbers, Clobbers, RParenLoc);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos;
|
|
SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos;
|
|
@@ -337,9 +347,12 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
|
TargetInfo::ConstraintInfo Info(Literal->getString(), InputName);
|
|
TargetInfo::ConstraintInfo Info(Literal->getString(), InputName);
|
|
if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,
|
|
if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,
|
|
Info)) {
|
|
Info)) {
|
|
- return StmtResult(targetDiag(Literal->getBeginLoc(),
|
|
|
|
- diag::err_asm_invalid_input_constraint)
|
|
|
|
- << Info.getConstraintStr());
|
|
|
|
|
|
+ targetDiag(Literal->getBeginLoc(), diag::err_asm_invalid_input_constraint)
|
|
|
|
+ << Info.getConstraintStr();
|
|
|
|
+ return new (Context)
|
|
|
|
+ GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs,
|
|
|
|
+ NumInputs, Names, Constraints, Exprs.data(), AsmString,
|
|
|
|
+ NumClobbers, Clobbers, RParenLoc);
|
|
}
|
|
}
|
|
|
|
|
|
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
|
|
ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
|
|
@@ -423,10 +436,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
|
|
|
|
|
StringRef Clobber = Literal->getString();
|
|
StringRef Clobber = Literal->getString();
|
|
|
|
|
|
- if (!Context.getTargetInfo().isValidClobber(Clobber))
|
|
|
|
- return StmtResult(targetDiag(Literal->getBeginLoc(),
|
|
|
|
- diag::err_asm_unknown_register_name)
|
|
|
|
- << Clobber);
|
|
|
|
|
|
+ if (!Context.getTargetInfo().isValidClobber(Clobber)) {
|
|
|
|
+ targetDiag(Literal->getBeginLoc(), diag::err_asm_unknown_register_name)
|
|
|
|
+ << Clobber;
|
|
|
|
+ return new (Context)
|
|
|
|
+ GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs,
|
|
|
|
+ NumInputs, Names, Constraints, Exprs.data(), AsmString,
|
|
|
|
+ NumClobbers, Clobbers, RParenLoc);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
GCCAsmStmt *NS =
|
|
GCCAsmStmt *NS =
|
|
@@ -437,10 +454,11 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
|
// have.
|
|
// have.
|
|
SmallVector<GCCAsmStmt::AsmStringPiece, 8> Pieces;
|
|
SmallVector<GCCAsmStmt::AsmStringPiece, 8> Pieces;
|
|
unsigned DiagOffs;
|
|
unsigned DiagOffs;
|
|
- if (unsigned DiagID = NS->AnalyzeAsmString(Pieces, Context, DiagOffs))
|
|
|
|
- return StmtResult(
|
|
|
|
- targetDiag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID)
|
|
|
|
- << AsmString->getSourceRange());
|
|
|
|
|
|
+ if (unsigned DiagID = NS->AnalyzeAsmString(Pieces, Context, DiagOffs)) {
|
|
|
|
+ targetDiag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID)
|
|
|
|
+ << AsmString->getSourceRange();
|
|
|
|
+ return NS;
|
|
|
|
+ }
|
|
|
|
|
|
// Validate constraints and modifiers.
|
|
// Validate constraints and modifiers.
|
|
for (unsigned i = 0, e = Pieces.size(); i != e; ++i) {
|
|
for (unsigned i = 0, e = Pieces.size(); i != e; ++i) {
|
|
@@ -496,13 +514,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
|
TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i];
|
|
TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i];
|
|
StringRef ConstraintStr = Info.getConstraintStr();
|
|
StringRef ConstraintStr = Info.getConstraintStr();
|
|
unsigned AltCount = ConstraintStr.count(',') + 1;
|
|
unsigned AltCount = ConstraintStr.count(',') + 1;
|
|
- if (NumAlternatives == ~0U)
|
|
|
|
|
|
+ if (NumAlternatives == ~0U) {
|
|
NumAlternatives = AltCount;
|
|
NumAlternatives = AltCount;
|
|
- else if (NumAlternatives != AltCount)
|
|
|
|
- return StmtResult(
|
|
|
|
- targetDiag(NS->getOutputExpr(i)->getBeginLoc(),
|
|
|
|
- diag::err_asm_unexpected_constraint_alternatives)
|
|
|
|
- << NumAlternatives << AltCount);
|
|
|
|
|
|
+ } else if (NumAlternatives != AltCount) {
|
|
|
|
+ targetDiag(NS->getOutputExpr(i)->getBeginLoc(),
|
|
|
|
+ diag::err_asm_unexpected_constraint_alternatives)
|
|
|
|
+ << NumAlternatives << AltCount;
|
|
|
|
+ return NS;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
SmallVector<size_t, 4> InputMatchedToOutput(OutputConstraintInfos.size(),
|
|
SmallVector<size_t, 4> InputMatchedToOutput(OutputConstraintInfos.size(),
|
|
~0U);
|
|
~0U);
|
|
@@ -510,13 +529,14 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
|
TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
|
|
TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
|
|
StringRef ConstraintStr = Info.getConstraintStr();
|
|
StringRef ConstraintStr = Info.getConstraintStr();
|
|
unsigned AltCount = ConstraintStr.count(',') + 1;
|
|
unsigned AltCount = ConstraintStr.count(',') + 1;
|
|
- if (NumAlternatives == ~0U)
|
|
|
|
|
|
+ if (NumAlternatives == ~0U) {
|
|
NumAlternatives = AltCount;
|
|
NumAlternatives = AltCount;
|
|
- else if (NumAlternatives != AltCount)
|
|
|
|
- return StmtResult(
|
|
|
|
- targetDiag(NS->getInputExpr(i)->getBeginLoc(),
|
|
|
|
- diag::err_asm_unexpected_constraint_alternatives)
|
|
|
|
- << NumAlternatives << AltCount);
|
|
|
|
|
|
+ } else if (NumAlternatives != AltCount) {
|
|
|
|
+ targetDiag(NS->getInputExpr(i)->getBeginLoc(),
|
|
|
|
+ diag::err_asm_unexpected_constraint_alternatives)
|
|
|
|
+ << NumAlternatives << AltCount;
|
|
|
|
+ return NS;
|
|
|
|
+ }
|
|
|
|
|
|
// If this is a tied constraint, verify that the output and input have
|
|
// If this is a tied constraint, verify that the output and input have
|
|
// either exactly the same type, or that they are int/ptr operands with the
|
|
// either exactly the same type, or that they are int/ptr operands with the
|
|
@@ -534,11 +554,10 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
|
targetDiag(NS->getInputExpr(i)->getBeginLoc(),
|
|
targetDiag(NS->getInputExpr(i)->getBeginLoc(),
|
|
diag::err_asm_input_duplicate_match)
|
|
diag::err_asm_input_duplicate_match)
|
|
<< TiedTo;
|
|
<< TiedTo;
|
|
- return StmtResult(
|
|
|
|
- targetDiag(
|
|
|
|
- NS->getInputExpr(InputMatchedToOutput[TiedTo])->getBeginLoc(),
|
|
|
|
- diag::note_asm_input_duplicate_first)
|
|
|
|
- << TiedTo);
|
|
|
|
|
|
+ targetDiag(NS->getInputExpr(InputMatchedToOutput[TiedTo])->getBeginLoc(),
|
|
|
|
+ diag::note_asm_input_duplicate_first)
|
|
|
|
+ << TiedTo;
|
|
|
|
+ return NS;
|
|
}
|
|
}
|
|
InputMatchedToOutput[TiedTo] = i;
|
|
InputMatchedToOutput[TiedTo] = i;
|
|
|
|
|
|
@@ -623,10 +642,10 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- return StmtResult(targetDiag(InputExpr->getBeginLoc(),
|
|
|
|
- diag::err_asm_tying_incompatible_types)
|
|
|
|
- << InTy << OutTy << OutputExpr->getSourceRange()
|
|
|
|
- << InputExpr->getSourceRange());
|
|
|
|
|
|
+ targetDiag(InputExpr->getBeginLoc(), diag::err_asm_tying_incompatible_types)
|
|
|
|
+ << InTy << OutTy << OutputExpr->getSourceRange()
|
|
|
|
+ << InputExpr->getSourceRange();
|
|
|
|
+ return NS;
|
|
}
|
|
}
|
|
|
|
|
|
// Check for conflicts between clobber list and input or output lists
|
|
// Check for conflicts between clobber list and input or output lists
|
|
@@ -634,8 +653,7 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
|
|
getClobberConflictLocation(Exprs, Constraints, Clobbers, NumClobbers,
|
|
getClobberConflictLocation(Exprs, Constraints, Clobbers, NumClobbers,
|
|
Context.getTargetInfo(), Context);
|
|
Context.getTargetInfo(), Context);
|
|
if (ConstraintLoc.isValid())
|
|
if (ConstraintLoc.isValid())
|
|
- return StmtResult(
|
|
|
|
- targetDiag(ConstraintLoc, diag::error_inoutput_conflict_with_clobber));
|
|
|
|
|
|
+ targetDiag(ConstraintLoc, diag::error_inoutput_conflict_with_clobber);
|
|
|
|
|
|
return NS;
|
|
return NS;
|
|
}
|
|
}
|