24 #include "llvm/ADT/ArrayRef.h"
25 #include "llvm/ADT/BitVector.h"
26 #include "llvm/MC/MCParser/MCAsmParser.h"
27 using namespace clang;
50 S.
Diag(E2->getLocStart(), diag::err_invalid_asm_cast_lvalue)
51 << E->getSourceRange();
53 S.
Diag(E2->getLocStart(), diag::warn_invalid_asm_cast_lvalue)
54 << E->getSourceRange();
67 for (
unsigned p = 0, e = AsmStrPieces.size(); p != e; ++p) {
83 if (!Func->hasAttr<NakedAttr>())
87 WorkList.push_back(E);
88 while (WorkList.size()) {
89 Expr *E = WorkList.pop_back_val();
90 if (isa<CXXThisExpr>(E)) {
91 S.
Diag(E->getLocStart(), diag::err_asm_naked_this_ref);
92 S.
Diag(Func->getAttr<NakedAttr>()->getLocation(), diag::note_attribute);
96 if (isa<ParmVarDecl>(DRE->getDecl())) {
97 S.
Diag(DRE->getLocStart(), diag::err_asm_naked_parm_ref);
98 S.
Diag(Func->getAttr<NakedAttr>()->getLocation(), diag::note_attribute);
102 for (
Stmt *Child : E->children()) {
103 if (
Expr *E = dyn_cast_or_null<Expr>(Child))
104 WorkList.push_back(E);
114 bool is_input_expr) {
120 } EType = ExprSafeType;
125 EType = ExprBitfield;
127 EType = ExprVectorElt;
129 EType = ExprGlobalRegVar;
131 if (EType != ExprSafeType) {
132 S.
Diag(E->getLocStart(), diag::err_asm_non_addr_value_in_memory_constraint)
134 << E->getSourceRange();
142 bool IsVolatile,
unsigned NumOutputs,
147 unsigned NumClobbers = clobbers.size();
162 Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names,
163 Constraints, Exprs.data(), AsmString, NumClobbers, Clobbers, RParenLoc);
167 for (
unsigned i = 0; i != NumOutputs; i++) {
171 StringRef OutputName;
173 OutputName = Names[i]->
getName();
178 diag::err_asm_invalid_output_constraint)
179 << Info.getConstraintStr());
181 ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
187 Expr *OutputExpr = Exprs[i];
194 if (Info.allowsMemory() &&
198 OutputConstraintInfos.push_back(Info);
215 if (!getLangOpts().HeinousExtensions) {
216 Diag(LVal->getLocStart(), diag::err_invalid_asm_cast_lvalue)
217 << OutputExpr->getSourceRange();
219 Diag(LVal->getLocStart(), diag::warn_invalid_asm_cast_lvalue)
220 << OutputExpr->getSourceRange();
227 if (RequireCompleteType(OutputExpr->getLocStart(), Exprs[i]->getType(),
228 diag::err_dereference_incomplete_type))
232 diag::err_asm_invalid_lvalue_in_output)
233 << OutputExpr->getSourceRange());
240 diag::err_asm_invalid_output_size)
241 << Info.getConstraintStr());
246 for (
unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) {
252 InputName = Names[i]->
getName();
258 diag::err_asm_invalid_input_constraint)
259 << Info.getConstraintStr());
262 ExprResult ER = CheckPlaceholderExpr(Exprs[i]);
267 Expr *InputExpr = Exprs[i];
274 if (Info.allowsMemory() &&
279 if (Info.allowsMemory() && !Info.allowsRegister()) {
282 diag::err_asm_invalid_lvalue_in_input)
283 << Info.getConstraintStr()
284 << InputExpr->getSourceRange());
285 }
else if (Info.requiresImmediateConstant() && !Info.allowsRegister()) {
290 Diag(InputExpr->getLocStart(), diag::err_asm_immediate_expected)
291 << Info.getConstraintStr() << InputExpr->getSourceRange());
292 if (!Info.isValidAsmImmediate(Result))
294 diag::err_invalid_asm_value_for_constraint)
295 << Result.toString(10) << Info.getConstraintStr()
296 << InputExpr->getSourceRange());
304 Exprs[i] = Result.
get();
307 if (Info.allowsRegister()) {
310 diag::err_asm_invalid_type_in_input)
311 << InputExpr->
getType() << Info.getConstraintStr()
312 << InputExpr->getSourceRange());
316 InputConstraintInfos.push_back(Info);
318 const Type *Ty = Exprs[i]->getType().getTypePtr();
322 if (!Ty->
isVoidType() || !Info.allowsMemory())
323 if (RequireCompleteType(InputExpr->getLocStart(), Exprs[i]->getType(),
324 diag::err_dereference_incomplete_type))
331 diag::err_asm_invalid_input_size)
332 << Info.getConstraintStr());
336 for (
unsigned i = 0; i != NumClobbers; i++) {
340 StringRef Clobber = Literal->
getString();
344 diag::err_asm_unknown_register_name) << Clobber);
349 NumInputs, Names, Constraints, Exprs.data(),
350 AsmString, NumClobbers, Clobbers, RParenLoc);
356 Diag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID)
357 << AsmString->getSourceRange();
362 for (
unsigned i = 0, e = Pieces.size(); i != e; ++i) {
372 if (ConstraintIdx >= NumOperands) {
375 for (
unsigned Cnt = ConstraintIdx - NumOperands; I !=
E; ++
I)
376 if (OutputConstraintInfos[I].isReadWrite() && Cnt-- == 0) {
381 assert(I !=
E &&
"Invalid operand number should have been caught in "
382 " AnalyzeAsmString");
387 const Type *Ty = Exprs[ConstraintIdx]->getType().getTypePtr();
392 std::string SuggestedModifier;
395 SuggestedModifier)) {
396 Diag(Exprs[ConstraintIdx]->getLocStart(),
397 diag::warn_asm_mismatched_size_modifier);
399 if (!SuggestedModifier.empty()) {
401 diag::note_asm_missing_constraint_modifier)
402 << SuggestedModifier;
403 SuggestedModifier =
"%" + SuggestedModifier + Piece.
getString();
411 unsigned NumAlternatives = ~0U;
412 for (
unsigned i = 0, e = OutputConstraintInfos.size(); i != e; ++i) {
415 unsigned AltCount = ConstraintStr.count(
',') + 1;
416 if (NumAlternatives == ~0U)
417 NumAlternatives = AltCount;
418 else if (NumAlternatives != AltCount)
420 diag::err_asm_unexpected_constraint_alternatives)
421 << NumAlternatives << AltCount);
425 for (
unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) {
428 unsigned AltCount = ConstraintStr.count(
',') + 1;
429 if (NumAlternatives == ~0U)
430 NumAlternatives = AltCount;
431 else if (NumAlternatives != AltCount)
433 diag::err_asm_unexpected_constraint_alternatives)
434 << NumAlternatives << AltCount);
442 unsigned InputOpNo = i+NumOutputs;
443 Expr *OutputExpr = Exprs[TiedTo];
444 Expr *InputExpr = Exprs[InputOpNo];
447 assert(TiedTo < InputMatchedToOutput.size() &&
"TiedTo value out of range");
448 if (InputMatchedToOutput[TiedTo] != ~0U) {
450 diag::err_asm_input_duplicate_match)
453 diag::note_asm_input_duplicate_first)
457 InputMatchedToOutput[TiedTo] = i;
470 AD_Int, AD_FP, AD_Other
471 } InputDomain, OutputDomain;
474 InputDomain = AD_Int;
478 InputDomain = AD_Other;
481 OutputDomain = AD_Int;
483 OutputDomain = AD_FP;
485 OutputDomain = AD_Other;
495 if (OutSize == InSize && InputDomain == OutputDomain &&
496 InputDomain != AD_Other)
502 bool SmallerValueMentioned =
false;
510 SmallerValueMentioned |= InSize < OutSize;
515 SmallerValueMentioned |= OutSize < InSize;
521 if (!SmallerValueMentioned && InputDomain != AD_Other &&
522 OutputConstraintInfos[TiedTo].allowsRegister())
529 if (InputDomain == AD_Int && OutputDomain == AD_Int &&
533 (OutTy->
isBooleanType() ? CK_IntegralToBoolean : CK_IntegralCast);
534 InputExpr = ImpCastExprToType(InputExpr, OutTy, castKind).get();
535 Exprs[InputOpNo] = InputExpr;
540 Diag(InputExpr->getLocStart(),
541 diag::err_asm_tying_incompatible_types)
542 << InTy << OutTy << OutputExpr->getSourceRange()
543 << InputExpr->getSourceRange();
551 llvm::InlineAsmIdentifierInfo &Info) {
557 Info.Length = Info.Size / Info.Type;
564 llvm::InlineAsmIdentifierInfo &Info,
565 bool IsUnevaluatedContext) {
568 if (IsUnevaluatedContext)
569 PushExpressionEvaluationContext(UnevaluatedAbstract,
570 ReuseLambdaContextDecl);
578 if (IsUnevaluatedContext)
579 PopExpressionEvaluationContext();
581 if (!Result.
isUsable())
return Result;
583 Result = CheckPlaceholderExpr(Result.
get());
584 if (!Result.
isUsable())
return Result;
602 if (RequireCompleteExprType(Result.
get(), diag::err_asm_incomplete_type)) {
610 Info.IsVarDecl =
true;
619 Member.split(Members,
".");
630 for (StringRef NextMember : Members) {
632 if (
VarDecl *VD = dyn_cast<VarDecl>(FoundDecl))
635 MarkAnyDeclReferenced(TD->getLocation(), TD,
false);
637 }
else if (
TypeDecl *TD = dyn_cast<TypeDecl>(FoundDecl))
639 else if (
FieldDecl *TD = dyn_cast<FieldDecl>(FoundDecl))
644 if (RequireCompleteType(AsmLoc,
QualType(RT, 0),
645 diag::err_asm_incomplete_type))
651 if (!LookupQualifiedName(FieldResult, RT->
getDecl()))
654 if (!FieldResult.isSingleResult())
656 FoundDecl = FieldResult.getFoundDecl();
674 llvm::InlineAsmIdentifierInfo &Info,
686 nullptr, NameInfo,
nullptr);
697 if (!LookupQualifiedName(FieldResult, RT->
getDecl()))
713 Info.OpDecl = Result.
get();
718 Info.IsVarDecl =
true;
726 unsigned NumOutputs,
unsigned NumInputs,
731 bool IsSimple = (NumOutputs != 0 || NumInputs != 0);
732 getCurFunction()->setHasBranchProtectedScope();
735 true, AsmToks, NumOutputs, NumInputs,
736 Constraints, Exprs, AsmString,
744 LabelDecl* Label = LookupOrCreateLabel(PP.getIdentifierInfo(ExternalLabelName),
752 std::string InternalName;
753 llvm::raw_string_ostream OS(InternalName);
757 OS <<
"__MSASMLABEL_." << MSAsmLabelNameCounter++ <<
"__";
758 for (
auto it = ExternalLabelName.begin(); it != ExternalLabelName.end();
775 Label->setLocation(Location);
This represents a GCC inline-assembly statement extension.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
unsigned getNumOutputs() const
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
A (possibly-)qualified type.
SourceLocation getBegin() const
static CXXDependentScopeMemberExpr * Create(const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs)
const LangOptions & getLangOpts() const
StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, IdentifierInfo **Names, MultiExprArg Constraints, MultiExprArg Exprs, Expr *AsmString, MultiExprArg Clobbers, SourceLocation RParenLoc)
ActionResult< Expr * > ExprResult
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
The base class of the type hierarchy.
bool validateOutputConstraint(ConstraintInfo &Info) const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
bool validateInputConstraint(MutableArrayRef< ConstraintInfo > OutputConstraints, ConstraintInfo &info) const
bool isBooleanType() const
SourceLocation getLocStart() const LLVM_READONLY
void setInputExpr(unsigned i, Expr *E)
VarDecl - An instance of this class is created to represent a variable declaration or definition...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
virtual bool validateConstraintModifier(StringRef, char, unsigned, std::string &) const
Defines the clang::Expr interface and subclasses for C++ expressions.
static void fillInlineAsmTypeInfo(const ASTContext &Context, QualType T, llvm::InlineAsmIdentifierInfo &Info)
const std::string & getConstraintStr() const
static bool checkExprMemoryConstraintCompat(Sema &S, Expr *E, TargetInfo::ConstraintInfo &Info, bool is_input_expr)
Returns true if given expression is not compatible with inline assembly's memory constraint; false ot...
bool refersToGlobalRegisterVar() const
Returns whether this expression refers to a global register variable.
One of these records is kept for each identifier that is lexed.
unsigned getNumInputs() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
A C++ nested-name-specifier augmented with source location information.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
void setName(DeclarationName N)
setName - Sets the embedded declaration name.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
virtual bool validateOutputSize(StringRef, unsigned) const
bool refersToVectorElement() const
Returns whether this expression refers to a vector element.
static bool isOperandMentioned(unsigned OpNo, ArrayRef< GCCAsmStmt::AsmStringPiece > AsmStrPieces)
isOperandMentioned - Return true if the specified operand # is mentioned anywhere in the decomposed a...
LabelDecl * GetOrCreateMSAsmLabel(StringRef ExternalLabelName, SourceLocation Location, bool AlwaysCreate)
virtual bool validateInputSize(StringRef, unsigned) const
Type(TypeClass tc, QualType canon, bool Dependent, bool InstantiationDependent, bool VariablyModified, bool ContainsUnexpandedParameterPack)
Represents a C++ unqualified-id that has been parsed.
Represents the results of name lookup.
const TargetInfo & getTargetInfo() const
CharUnits - This is an opaque type for sizes expressed in character units.
static bool CheckAsmLValue(const Expr *E, Sema &S)
CheckAsmLValue - GNU C has an extremely ugly extension whereby they silently ignore "noop" casts in p...
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
TypeDecl - Represents a declaration of a type.
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
Expr * getOutputExpr(unsigned i)
RecordDecl * getDecl() const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
Represents a C++ nested-name-specifier or a global scope specifier.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
detail::InMemoryDirectory::const_iterator I
ExprResult LookupInlineAsmVarDeclField(Expr *RefExpr, StringRef Member, llvm::InlineAsmIdentifierInfo &Info, SourceLocation AsmLoc)
Sema - This implements semantic analysis and AST building for C.
Expr * IgnoreParenNoopCasts(ASTContext &Ctx) LLVM_READONLY
IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the value (including ptr->int ...
CastKind
CastKind - The kind of operation required for a conversion.
ExprResult LookupInlineAsmIdentifier(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, llvm::InlineAsmIdentifierInfo &Info, bool IsUnevaluatedContext)
static bool CheckNakedParmReference(Expr *E, Sema &S)
bool isRealFloatingType() const
Floating point categories.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
StringRef getName() const
Return the actual identifier string.
AsmStringPiece - this is part of a decomposed asm string specification (for use with the AnalyzeAsmSt...
bool isValidClobber(StringRef Name) const
Returns whether the passed in string is a valid clobber in an inline asm statement.
Defines the clang::Preprocessor interface.
bool isMSAsmLabel() const
isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type, does not have an incomplet...
Defines the clang::TypeLoc interface and its subclasses.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
This represents a Microsoft inline-assembly statement extension.
unsigned getTiedOperand() const
The result type of a method or function.
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Encodes a location in the source.
char getModifier() const
getModifier - Get the modifier for this operand, if present.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
LabelDecl - Represents the declaration of a label.
CharSourceRange getRange() const
bool LookupInlineAsmField(StringRef Base, StringRef Member, unsigned &Offset, SourceLocation AsmLoc)
Expr * getInputExpr(unsigned i)
bool isTypeDependent() const
isTypeDependent - Determines whether this expression is type-dependent (C++ [temp.dep.expr]), which means that its type could change from one template instantiation to the next.
ActionResult< CXXBaseSpecifier * > BaseResult
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
Base class for declarations which introduce a typedef-name.
unsigned AnalyzeAsmString(SmallVectorImpl< AsmStringPiece > &Pieces, const ASTContext &C, unsigned &DiagOffs) const
AnalyzeAsmString - Analyze the asm string of the current asm, decomposing it into pieces...
IndirectFieldDecl - An instance of this class is created to represent a field injected from an anonym...
bool hasTiedOperand() const
Return true if this input operand is a matching constraint that ties it to an output operand...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
StringRef getString() const
detail::InMemoryDirectory::const_iterator E
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
bool DeclAttrsMatchCUDAMode(const LangOptions &LangOpts, Decl *D)
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
const T * getAs() const
Member-template getAs<specific type>'.
bool isFunctionType() const
unsigned getOperandNo() const
unsigned getFieldIndex() const
getFieldIndex - Returns the index of this field within its record, as appropriate for passing to ASTR...
void setLoc(SourceLocation L)
setLoc - Sets the main location of the declaration name.
const std::string & getString() const
void setMSAsmLabel(StringRef Name)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string...
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, ArrayRef< Token > AsmToks, StringRef AsmString, unsigned NumOutputs, unsigned NumInputs, ArrayRef< StringRef > Constraints, ArrayRef< StringRef > Clobbers, ArrayRef< Expr * > Exprs, SourceLocation EndLoc)
A reference to a declared variable, function, enum, etc.
QualType getElementType() const
void setMSAsmLabelResolved()
NamedDecl - This represents a decl with a name.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool isPointerType() const