13d45a7739bae1e9c53c94ebb38c4339bd8ec0ca6Chad Rosier//===--- SemaStmtAsm.cpp - Semantic Analysis for Asm Statements -----------===// 24b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// 34b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// The LLVM Compiler Infrastructure 44b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// 54b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// This file is distributed under the University of Illinois Open Source 64b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// License. See LICENSE.TXT for details. 74b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// 84b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier//===----------------------------------------------------------------------===// 94b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// 104b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// This file implements semantic analysis for inline asm statements. 114b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier// 124b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier//===----------------------------------------------------------------------===// 134b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 144b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "clang/Sema/SemaInternal.h" 15802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier#include "clang/AST/RecordLayout.h" 164b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "clang/AST/TypeLoc.h" 174b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "clang/Basic/TargetInfo.h" 1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Initialization.h" 1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Lookup.h" 2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/Scope.h" 2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Sema/ScopeInfo.h" 224b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/ADT/ArrayRef.h" 234b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier#include "llvm/ADT/BitVector.h" 24ef8225444452a1486bd721f3285301fe84643b00Stephen Hines#include "llvm/MC/MCParser/MCAsmParser.h" 254b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosierusing namespace clang; 264b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosierusing namespace sema; 274b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 284b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// CheckAsmLValue - GNU C has an extremely ugly extension whereby they silently 294b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// ignore "noop" casts in places where an lvalue is required by an inline asm. 304b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// We emulate this behavior when -fheinous-gnu-extensions is specified, but 314b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// provide a strong guidance to not use it. 324b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// 334b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// This method checks to see if the argument is an acceptable l-value and 344b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// returns false if it is a case we can handle. 354b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosierstatic bool CheckAsmLValue(const Expr *E, Sema &S) { 364b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Type dependent expressions will be checked during instantiation. 374b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (E->isTypeDependent()) 384b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return false; 394b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 404b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (E->isLValue()) 414b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return false; // Cool, this is an lvalue. 424b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 434b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Okay, this is not an lvalue, but perhaps it is the result of a cast that we 444b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // are supposed to allow. 454b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier const Expr *E2 = E->IgnoreParenNoopCasts(S.Context); 464b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (E != E2 && E2->isLValue()) { 474b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!S.getLangOpts().HeinousExtensions) 484b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier S.Diag(E2->getLocStart(), diag::err_invalid_asm_cast_lvalue) 494b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << E->getSourceRange(); 504b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier else 514b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier S.Diag(E2->getLocStart(), diag::warn_invalid_asm_cast_lvalue) 524b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << E->getSourceRange(); 534b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Accept, even if we emitted an error diagnostic. 544b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return false; 554b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 564b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 574b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // None of the above, just randomly invalid non-lvalue. 584b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return true; 594b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier} 604b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 614b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// isOperandMentioned - Return true if the specified operand # is mentioned 624b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier/// anywhere in the decomposed asm string. 634b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosierstatic bool isOperandMentioned(unsigned OpNo, 64df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier ArrayRef<GCCAsmStmt::AsmStringPiece> AsmStrPieces) { 654b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier for (unsigned p = 0, e = AsmStrPieces.size(); p != e; ++p) { 66df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier const GCCAsmStmt::AsmStringPiece &Piece = AsmStrPieces[p]; 674b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Piece.isOperand()) continue; 684b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 694b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // If this is a reference to the input and if the input was the smaller 704b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // one, then we have to reject this asm. 714b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (Piece.getOperandNo() == OpNo) 724b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return true; 734b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 744b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return false; 754b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier} 764b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 77df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad RosierStmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, 78df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier bool IsVolatile, unsigned NumOutputs, 79df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier unsigned NumInputs, IdentifierInfo **Names, 8096c2473661be846174ffeb429fc567f6554952dfDmitri Gribenko MultiExprArg constraints, MultiExprArg Exprs, 81df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier Expr *asmString, MultiExprArg clobbers, 82df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier SourceLocation RParenLoc) { 834b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier unsigned NumClobbers = clobbers.size(); 844b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringLiteral **Constraints = 855354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer reinterpret_cast<StringLiteral**>(constraints.data()); 864b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringLiteral *AsmString = cast<StringLiteral>(asmString); 875354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer StringLiteral **Clobbers = reinterpret_cast<StringLiteral**>(clobbers.data()); 884b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 894b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos; 904b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 914b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // The parser verifies that there is a string literal here. 924b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!AsmString->isAscii()) 934b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(AsmString->getLocStart(),diag::err_asm_wide_character) 944b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << AsmString->getSourceRange()); 954b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 964b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier for (unsigned i = 0; i != NumOutputs; i++) { 974b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringLiteral *Literal = Constraints[i]; 984b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Literal->isAscii()) 994b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) 1004b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << Literal->getSourceRange()); 1014b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1024b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringRef OutputName; 1034b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (Names[i]) 1044b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OutputName = Names[i]->getName(); 1054b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1064b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName); 1074b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Context.getTargetInfo().validateOutputConstraint(Info)) 1084b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(Literal->getLocStart(), 1094b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier diag::err_asm_invalid_output_constraint) 1104b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << Info.getConstraintStr()); 1114b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1124b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Check that the output exprs are valid lvalues. 1134b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Expr *OutputExpr = Exprs[i]; 11414df23bd114919abc374b2bcd2b2e16b79936584Bill Wendling if (CheckAsmLValue(OutputExpr, *this)) 1154b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(OutputExpr->getLocStart(), 11614df23bd114919abc374b2bcd2b2e16b79936584Bill Wendling diag::err_asm_invalid_lvalue_in_output) 11714df23bd114919abc374b2bcd2b2e16b79936584Bill Wendling << OutputExpr->getSourceRange()); 11814df23bd114919abc374b2bcd2b2e16b79936584Bill Wendling 119d835d9496c55848981c1d9db383a0de1be160925Bill Wendling if (RequireCompleteType(OutputExpr->getLocStart(), Exprs[i]->getType(), 120d835d9496c55848981c1d9db383a0de1be160925Bill Wendling diag::err_dereference_incomplete_type)) 121d835d9496c55848981c1d9db383a0de1be160925Bill Wendling return StmtError(); 1224b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1234b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OutputConstraintInfos.push_back(Info); 1244b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 1254b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1264b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos; 1274b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1284b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) { 1294b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringLiteral *Literal = Constraints[i]; 1304b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Literal->isAscii()) 1314b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) 1324b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << Literal->getSourceRange()); 1334b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1344b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringRef InputName; 1354b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (Names[i]) 1364b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputName = Names[i]->getName(); 1374b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1384b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier TargetInfo::ConstraintInfo Info(Literal->getString(), InputName); 1394b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos.data(), 1404b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier NumOutputs, Info)) { 1414b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(Literal->getLocStart(), 1424b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier diag::err_asm_invalid_input_constraint) 1434b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << Info.getConstraintStr()); 1444b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 1454b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1464b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Expr *InputExpr = Exprs[i]; 1474b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1484b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Only allow void types for memory constraints. 1494b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (Info.allowsMemory() && !Info.allowsRegister()) { 1504b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (CheckAsmLValue(InputExpr, *this)) 1514b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(InputExpr->getLocStart(), 1524b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier diag::err_asm_invalid_lvalue_in_input) 1534b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << Info.getConstraintStr() 1544b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << InputExpr->getSourceRange()); 1554b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 1564b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1574b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (Info.allowsRegister()) { 1584b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (InputExpr->getType()->isVoidType()) { 1594b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(InputExpr->getLocStart(), 1604b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier diag::err_asm_invalid_type_in_input) 1614b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << InputExpr->getType() << Info.getConstraintStr() 1624b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << InputExpr->getSourceRange()); 1634b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 1644b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 1654b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1664b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier ExprResult Result = DefaultFunctionArrayLvalueConversion(Exprs[i]); 1674b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (Result.isInvalid()) 1684b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(); 1694b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 170ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Exprs[i] = Result.get(); 1714b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputConstraintInfos.push_back(Info); 17268fd608c2c0866064e974c3d43778c47c1cbb080Bill Wendling 17368fd608c2c0866064e974c3d43778c47c1cbb080Bill Wendling const Type *Ty = Exprs[i]->getType().getTypePtr(); 17414df23bd114919abc374b2bcd2b2e16b79936584Bill Wendling if (Ty->isDependentType()) 1756ceb377ae4e32eeed2647aacc4a7d5c4564641bfEric Christopher continue; 1766ceb377ae4e32eeed2647aacc4a7d5c4564641bfEric Christopher 17714df23bd114919abc374b2bcd2b2e16b79936584Bill Wendling if (!Ty->isVoidType() || !Info.allowsMemory()) 178d835d9496c55848981c1d9db383a0de1be160925Bill Wendling if (RequireCompleteType(InputExpr->getLocStart(), Exprs[i]->getType(), 179d835d9496c55848981c1d9db383a0de1be160925Bill Wendling diag::err_dereference_incomplete_type)) 180d835d9496c55848981c1d9db383a0de1be160925Bill Wendling return StmtError(); 18114df23bd114919abc374b2bcd2b2e16b79936584Bill Wendling 18268fd608c2c0866064e974c3d43778c47c1cbb080Bill Wendling unsigned Size = Context.getTypeSize(Ty); 18368fd608c2c0866064e974c3d43778c47c1cbb080Bill Wendling if (!Context.getTargetInfo().validateInputSize(Literal->getString(), 18468fd608c2c0866064e974c3d43778c47c1cbb080Bill Wendling Size)) 18568fd608c2c0866064e974c3d43778c47c1cbb080Bill Wendling return StmtError(Diag(InputExpr->getLocStart(), 18668fd608c2c0866064e974c3d43778c47c1cbb080Bill Wendling diag::err_asm_invalid_input_size) 18768fd608c2c0866064e974c3d43778c47c1cbb080Bill Wendling << Info.getConstraintStr()); 1884b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 1894b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1904b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Check that the clobbers are valid. 1914b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier for (unsigned i = 0; i != NumClobbers; i++) { 1924b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringLiteral *Literal = Clobbers[i]; 1934b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Literal->isAscii()) 1944b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) 1954b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << Literal->getSourceRange()); 1964b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1974b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier StringRef Clobber = Literal->getString(); 1984b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 1994b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Context.getTargetInfo().isValidClobber(Clobber)) 2004b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(Diag(Literal->getLocStart(), 2014b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier diag::err_asm_unknown_register_name) << Clobber); 2024b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 2034b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 204df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier GCCAsmStmt *NS = 205df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier new (Context) GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, 20696c2473661be846174ffeb429fc567f6554952dfDmitri Gribenko NumInputs, Names, Constraints, Exprs.data(), 20796c2473661be846174ffeb429fc567f6554952dfDmitri Gribenko AsmString, NumClobbers, Clobbers, RParenLoc); 2084b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Validate the asm string, ensuring it makes sense given the operands we 2094b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // have. 210df5faf5e7ae6823d0af0b801c4ac26d47f2cee97Chad Rosier SmallVector<GCCAsmStmt::AsmStringPiece, 8> Pieces; 2114b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier unsigned DiagOffs; 2124b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (unsigned DiagID = NS->AnalyzeAsmString(Pieces, Context, DiagOffs)) { 2134b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Diag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID) 2144b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << AsmString->getSourceRange(); 2154b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(); 2164b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 2174b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 21850d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling // Validate constraints and modifiers. 21950d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling for (unsigned i = 0, e = Pieces.size(); i != e; ++i) { 22050d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling GCCAsmStmt::AsmStringPiece &Piece = Pieces[i]; 22150d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling if (!Piece.isOperand()) continue; 22250d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling 22350d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling // Look for the correct constraint index. 22450d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling unsigned Idx = 0; 22550d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling unsigned ConstraintIdx = 0; 22650d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling for (unsigned i = 0, e = NS->getNumOutputs(); i != e; ++i, ++ConstraintIdx) { 22750d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i]; 22850d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling if (Idx == Piece.getOperandNo()) 22950d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling break; 23050d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling ++Idx; 23150d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling 23250d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling if (Info.isReadWrite()) { 23350d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling if (Idx == Piece.getOperandNo()) 23450d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling break; 23550d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling ++Idx; 23650d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling } 23750d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling } 23850d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling 23950d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling for (unsigned i = 0, e = NS->getNumInputs(); i != e; ++i, ++ConstraintIdx) { 24050d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i]; 24150d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling if (Idx == Piece.getOperandNo()) 24250d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling break; 24350d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling ++Idx; 24450d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling 24550d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling if (Info.isReadWrite()) { 24650d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling if (Idx == Piece.getOperandNo()) 24750d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling break; 24850d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling ++Idx; 24950d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling } 25050d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling } 25150d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling 25250d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling // Now that we have the right indexes go ahead and check. 25350d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling StringLiteral *Literal = Constraints[ConstraintIdx]; 25450d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling const Type *Ty = Exprs[ConstraintIdx]->getType().getTypePtr(); 25550d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling if (Ty->isDependentType() || Ty->isIncompleteType()) 25650d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling continue; 25750d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling 25850d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling unsigned Size = Context.getTypeSize(Ty); 25950d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling if (!Context.getTargetInfo() 26050d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling .validateConstraintModifier(Literal->getString(), Piece.getModifier(), 26150d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling Size)) 26250d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling Diag(Exprs[ConstraintIdx]->getLocStart(), 26350d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling diag::warn_asm_mismatched_size_modifier); 26450d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling } 26550d46caf00c743312e0ea1f87a693d504b12ef51Bill Wendling 2664b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Validate tied input operands for type mismatches. 2674b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) { 2684b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i]; 2694b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2704b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // If this is a tied constraint, verify that the output and input have 2714b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // either exactly the same type, or that they are int/ptr operands with the 2724b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // same size (int/long, int*/long, are ok etc). 2734b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!Info.hasTiedOperand()) continue; 2744b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2754b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier unsigned TiedTo = Info.getTiedOperand(); 2764b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier unsigned InputOpNo = i+NumOutputs; 2774b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Expr *OutputExpr = Exprs[TiedTo]; 2784b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Expr *InputExpr = Exprs[InputOpNo]; 2794b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2804b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (OutputExpr->isTypeDependent() || InputExpr->isTypeDependent()) 2814b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier continue; 2824b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2834b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier QualType InTy = InputExpr->getType(); 2844b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier QualType OutTy = OutputExpr->getType(); 2854b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (Context.hasSameType(InTy, OutTy)) 2864b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier continue; // All types can be tied to themselves. 2874b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2884b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Decide if the input and output are in the same domain (integer/ptr or 2894b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // floating point. 2904b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier enum AsmDomain { 2914b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier AD_Int, AD_FP, AD_Other 2924b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } InputDomain, OutputDomain; 2934b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 2944b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (InTy->isIntegerType() || InTy->isPointerType()) 2954b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputDomain = AD_Int; 2964b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier else if (InTy->isRealFloatingType()) 2974b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputDomain = AD_FP; 2984b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier else 2994b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputDomain = AD_Other; 3004b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 3014b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (OutTy->isIntegerType() || OutTy->isPointerType()) 3024b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OutputDomain = AD_Int; 3034b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier else if (OutTy->isRealFloatingType()) 3044b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OutputDomain = AD_FP; 3054b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier else 3064b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OutputDomain = AD_Other; 3074b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 3084b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // They are ok if they are the same size and in the same domain. This 3094b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // allows tying things like: 3104b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // void* to int* 3114b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // void* to int if they are the same size. 3124b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // double to long double if they are the same size. 3134b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // 3144b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier uint64_t OutSize = Context.getTypeSize(OutTy); 3154b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier uint64_t InSize = Context.getTypeSize(InTy); 3164b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (OutSize == InSize && InputDomain == OutputDomain && 3174b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputDomain != AD_Other) 3184b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier continue; 3194b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 3204b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // If the smaller input/output operand is not mentioned in the asm string, 3214b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // then we can promote the smaller one to a larger input and the asm string 3224b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // won't notice. 3234b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier bool SmallerValueMentioned = false; 3244b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 3254b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // If this is a reference to the input and if the input was the smaller 3264b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // one, then we have to reject this asm. 3274b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (isOperandMentioned(InputOpNo, Pieces)) { 3284b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // This is a use in the asm string of the smaller operand. Since we 3294b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // codegen this by promoting to a wider value, the asm will get printed 3304b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // "wrong". 3314b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SmallerValueMentioned |= InSize < OutSize; 3324b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 3334b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (isOperandMentioned(TiedTo, Pieces)) { 3344b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // If this is a reference to the output, and if the output is the larger 3354b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // value, then it's ok because we'll promote the input to the larger type. 3364b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier SmallerValueMentioned |= OutSize < InSize; 3374b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 3384b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 3394b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // If the smaller value wasn't mentioned in the asm string, and if the 3404b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // output was a register, just extend the shorter one to the size of the 3414b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // larger one. 3424b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (!SmallerValueMentioned && InputDomain != AD_Other && 3434b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier OutputConstraintInfos[TiedTo].allowsRegister()) 3444b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier continue; 3454b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 3464b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // Either both of the operands were mentioned or the smaller one was 3474b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // mentioned. One more special case that we'll allow: if the tied input is 3484b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // integer, unmentioned, and is a constant, then we'll allow truncating it 3494b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier // down to the size of the destination. 3504b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier if (InputDomain == AD_Int && OutputDomain == AD_Int && 3514b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier !isOperandMentioned(InputOpNo, Pieces) && 3524b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier InputExpr->isEvaluatable(Context)) { 3534b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier CastKind castKind = 3544b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier (OutTy->isBooleanType() ? CK_IntegralToBoolean : CK_IntegralCast); 355ef8225444452a1486bd721f3285301fe84643b00Stephen Hines InputExpr = ImpCastExprToType(InputExpr, OutTy, castKind).get(); 3564b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Exprs[InputOpNo] = InputExpr; 3574b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier NS->setInputExpr(i, InputExpr); 3584b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier continue; 3594b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 3604b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 3614b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier Diag(InputExpr->getLocStart(), 3624b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier diag::err_asm_tying_incompatible_types) 3634b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << InTy << OutTy << OutputExpr->getSourceRange() 3644b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier << InputExpr->getSourceRange(); 3654b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier return StmtError(); 3664b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier } 3674b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 368ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return NS; 3694b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier} 3704b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 371aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCallExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS, 372aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall SourceLocation TemplateKWLoc, 373aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall UnqualifiedId &Id, 374ef8225444452a1486bd721f3285301fe84643b00Stephen Hines llvm::InlineAsmIdentifierInfo &Info, 375aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall bool IsUnevaluatedContext) { 376aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall Info.clear(); 3774b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 378aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall if (IsUnevaluatedContext) 379aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall PushExpressionEvaluationContext(UnevaluatedAbstract, 380aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall ReuseLambdaContextDecl); 381d9b56edcf42232c5331f9ad79aae83ba31e852dfChad Rosier 382aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall ExprResult Result = ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Id, 383aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall /*trailing lparen*/ false, 384942dfe2e4d75f9d7c6f2e73eadac6fa659a5f853Chad Rosier /*is & operand*/ false, 3856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*CorrectionCandidateCallback=*/nullptr, 386942dfe2e4d75f9d7c6f2e73eadac6fa659a5f853Chad Rosier /*IsInlineAsmIdentifier=*/ true); 3874b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 388aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall if (IsUnevaluatedContext) 389aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall PopExpressionEvaluationContext(); 3904b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 391aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall if (!Result.isUsable()) return Result; 3924b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier 393ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Result = CheckPlaceholderExpr(Result.get()); 394aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall if (!Result.isUsable()) return Result; 3955f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman 396aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall QualType T = Result.get()->getType(); 397802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier 398aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall // For now, reject dependent types. 399aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall if (T->isDependentType()) { 400aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall Diag(Id.getLocStart(), diag::err_asm_incomplete_type) << T; 401aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall return ExprError(); 4025f1385b81b0a6c6878ff1e35118a5b0bf52ca930Eli Friedman } 403d9b56edcf42232c5331f9ad79aae83ba31e852dfChad Rosier 404aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall // Any sort of function type is fine. 405aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall if (T->isFunctionType()) { 406aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall return Result; 40787a9f2b2d7fb287ccd9ed5dfdbe75cc4ce906122Chad Rosier } 40887a9f2b2d7fb287ccd9ed5dfdbe75cc4ce906122Chad Rosier 409aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall // Otherwise, it needs to be a complete type. 410aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall if (RequireCompleteExprType(Result.get(), diag::err_asm_incomplete_type)) { 411aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall return ExprError(); 4127fd00b153c991fbe30f9fa76391d2ad9fa1d349dChad Rosier } 4137fd00b153c991fbe30f9fa76391d2ad9fa1d349dChad Rosier 414aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall // Compute the type size (and array length if applicable?). 415aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall Info.Type = Info.Size = Context.getTypeSizeInChars(T).getQuantity(); 416aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall if (T->isArrayType()) { 417aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall const ArrayType *ATy = Context.getAsArrayType(T); 418aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall Info.Type = Context.getTypeSizeInChars(ATy->getElementType()).getQuantity(); 419aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall Info.Length = Info.Size / Info.Type; 4207fd00b153c991fbe30f9fa76391d2ad9fa1d349dChad Rosier } 4217fd00b153c991fbe30f9fa76391d2ad9fa1d349dChad Rosier 422aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall // We can work with the expression as long as it's not an r-value. 423aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall if (!Result.get()->isRValue()) 4241e7ca6211c77208c8a339c2a26e612be81c70ec5Chad Rosier Info.IsVarDecl = true; 4257fd00b153c991fbe30f9fa76391d2ad9fa1d349dChad Rosier 426aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall return Result; 427d9b56edcf42232c5331f9ad79aae83ba31e852dfChad Rosier} 4282735df2eb16acfb92b8cd24e163e3a74a7a4d950Chad Rosier 429802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosierbool Sema::LookupInlineAsmField(StringRef Base, StringRef Member, 430802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier unsigned &Offset, SourceLocation AsmLoc) { 431802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier Offset = 0; 432802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier LookupResult BaseResult(*this, &Context.Idents.get(Base), SourceLocation(), 433802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier LookupOrdinaryName); 434802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier 435802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier if (!LookupName(BaseResult, getCurScope())) 436802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier return true; 437802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier 438802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier if (!BaseResult.isSingleResult()) 439802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier return true; 440802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier 4416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const RecordType *RT = nullptr; 442e3faa6ec8005f34b705cef363b071b933e111e1cChad Rosier NamedDecl *FoundDecl = BaseResult.getFoundDecl(); 443e3faa6ec8005f34b705cef363b071b933e111e1cChad Rosier if (VarDecl *VD = dyn_cast<VarDecl>(FoundDecl)) 444802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier RT = VD->getType()->getAs<RecordType>(); 4456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(FoundDecl)) 446802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier RT = TD->getUnderlyingType()->getAs<RecordType>(); 4476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else if (TypeDecl *TD = dyn_cast<TypeDecl>(FoundDecl)) 4486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines RT = TD->getTypeForDecl()->getAs<RecordType>(); 449802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier if (!RT) 450802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier return true; 451802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier 452802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier if (RequireCompleteType(AsmLoc, QualType(RT, 0), 0)) 453802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier return true; 454802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier 455802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier LookupResult FieldResult(*this, &Context.Idents.get(Member), SourceLocation(), 456802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier LookupMemberName); 457802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier 458802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier if (!LookupQualifiedName(FieldResult, RT->getDecl())) 459802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier return true; 460802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier 461802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier // FIXME: Handle IndirectFieldDecl? 462802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier FieldDecl *FD = dyn_cast<FieldDecl>(FieldResult.getFoundDecl()); 463802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier if (!FD) 464802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier return true; 465802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier 466802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier const ASTRecordLayout &RL = Context.getASTRecordLayout(RT->getDecl()); 467802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier unsigned i = FD->getFieldIndex(); 468802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier CharUnits Result = Context.toCharUnitsFromBits(RL.getFieldOffset(i)); 469802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier Offset = (unsigned)Result.getQuantity(); 470802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier 471802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier return false; 472802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier} 473802f93736a9ae76ffcbd90dbaf1c0b185531bb30Chad Rosier 474b55e602e1dc7952edc7545fab7bb7b15047378f3Chad RosierStmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, 475aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall ArrayRef<Token> AsmToks, 476aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall StringRef AsmString, 477aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall unsigned NumOutputs, unsigned NumInputs, 478aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall ArrayRef<StringRef> Constraints, 479aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall ArrayRef<StringRef> Clobbers, 480aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall ArrayRef<Expr*> Exprs, 481aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall SourceLocation EndLoc) { 482aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall bool IsSimple = (NumOutputs != 0 || NumInputs != 0); 4834b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier MSAsmStmt *NS = 4847fd00b153c991fbe30f9fa76391d2ad9fa1d349dChad Rosier new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple, 4857fd00b153c991fbe30f9fa76391d2ad9fa1d349dChad Rosier /*IsVolatile*/ true, AsmToks, NumOutputs, NumInputs, 486aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall Constraints, Exprs, AsmString, 487aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall Clobbers, EndLoc); 488ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return NS; 4894b5e48d39eb94ee12f3d89df60525053d8b0275eChad Rosier} 490