Index: include/clang/Parse/Parser.h =================================================================== --- include/clang/Parse/Parser.h +++ include/clang/Parse/Parser.h @@ -1474,7 +1474,6 @@ ExprResult ParseMSAsmIdentifier(llvm::SmallVectorImpl &LineToks, unsigned &NumLineToksConsumed, - void *Info, bool IsUnevaluated); private: Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -3768,15 +3768,15 @@ Expr *AsmString, MultiExprArg Clobbers, SourceLocation RParenLoc); + void FillInlineAsmIdentifierInfo(Expr *Res, + llvm::InlineAsmIdentifierInfo &Info); ExprResult LookupInlineAsmIdentifier(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, - llvm::InlineAsmIdentifierInfo &Info, bool IsUnevaluatedContext); bool LookupInlineAsmField(StringRef Base, StringRef Member, unsigned &Offset, SourceLocation AsmLoc); ExprResult LookupInlineAsmVarDeclField(Expr *RefExpr, StringRef Member, - llvm::InlineAsmIdentifierInfo &Info, SourceLocation AsmLoc); StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, ArrayRef AsmToks, Index: lib/Parse/ParseStmtAsm.cpp =================================================================== --- lib/Parse/ParseStmtAsm.cpp +++ lib/Parse/ParseStmtAsm.cpp @@ -54,9 +54,9 @@ assert(AsmToks.size() == AsmTokOffsets.size()); } - void *LookupInlineAsmIdentifier(StringRef &LineBuf, - llvm::InlineAsmIdentifierInfo &Info, - bool IsUnevaluatedContext) override { + void LookupInlineAsmIdentifier(StringRef &LineBuf, + llvm::InlineAsmIdentifierInfo &Info, + bool IsUnevaluatedContext) override { // Collect the desired tokens. SmallVector LineToks; const Token *FirstOrigToken = nullptr; @@ -64,7 +64,7 @@ unsigned NumConsumedToks; ExprResult Result = TheParser.ParseMSAsmIdentifier( - LineToks, NumConsumedToks, &Info, IsUnevaluatedContext); + LineToks, NumConsumedToks, IsUnevaluatedContext); // If we consumed the entire line, tell MC that. // Also do this if we consumed nothing as a way of reporting failure. @@ -89,9 +89,10 @@ LineBuf = LineBuf.substr(0, TotalOffset); } - // Initialize the "decl" with the lookup result. - Info.OpDecl = static_cast(Result.get()); - return Info.OpDecl; + // Initialize Info with the lookup result. + if (!Result.isUsable()) + return; + TheParser.getActions().FillInlineAsmIdentifierInfo(Result.get(), Info); } StringRef LookupInlineAsmLabel(StringRef Identifier, llvm::SourceMgr &LSM, @@ -183,11 +184,7 @@ /// about the actual type. ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl &LineToks, unsigned &NumLineToksConsumed, - void *CastInfo, bool IsUnevaluatedContext) { - llvm::InlineAsmIdentifierInfo &Info = - *(llvm::InlineAsmIdentifierInfo *)CastInfo; - // Push a fake token on the end so that we don't overrun the token // stream. We use ';' because it expression-parsing should never // overrun it. @@ -227,7 +224,7 @@ /*AllowDeductionGuide=*/false, /*ObjectType=*/nullptr, TemplateKWLoc, Id); // Perform the lookup. - Result = Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id, Info, + Result = Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id, IsUnevaluatedContext); } // While the next two tokens are 'period' 'identifier', repeatedly parse it as @@ -241,7 +238,7 @@ IdentifierInfo *Id = Tok.getIdentifierInfo(); ConsumeToken(); // Consume the identifier. Result = Actions.LookupInlineAsmVarDeclField(Result.get(), Id->getName(), - Info, Tok.getLocation()); + Tok.getLocation()); } // Figure out how many tokens we are into LineToks. Index: lib/Sema/SemaStmtAsm.cpp =================================================================== --- lib/Sema/SemaStmtAsm.cpp +++ lib/Sema/SemaStmtAsm.cpp @@ -48,10 +48,10 @@ if (E != E2 && E2->isLValue()) { if (!S.getLangOpts().HeinousExtensions) S.Diag(E2->getLocStart(), diag::err_invalid_asm_cast_lvalue) - << E->getSourceRange(); + << E->getSourceRange(); else S.Diag(E2->getLocStart(), diag::warn_invalid_asm_cast_lvalue) - << E->getSourceRange(); + << E->getSourceRange(); // Accept, even if we emitted an error diagnostic. return false; } @@ -62,11 +62,13 @@ /// isOperandMentioned - Return true if the specified operand # is mentioned /// anywhere in the decomposed asm string. -static bool isOperandMentioned(unsigned OpNo, - ArrayRef AsmStrPieces) { +static bool +isOperandMentioned(unsigned OpNo, + ArrayRef AsmStrPieces) { for (unsigned p = 0, e = AsmStrPieces.size(); p != e; ++p) { const GCCAsmStmt::AsmStringPiece &Piece = AsmStrPieces[p]; - if (!Piece.isOperand()) continue; + if (!Piece.isOperand()) + continue; // If this is a reference to the input and if the input was the smaller // one, then we have to reject this asm. @@ -605,23 +607,32 @@ return NS; } -static void fillInlineAsmTypeInfo(const ASTContext &Context, QualType T, - llvm::InlineAsmIdentifierInfo &Info) { - // Compute the type size (and array length if applicable?). - Info.Type = Info.Size = Context.getTypeSizeInChars(T).getQuantity(); - if (T->isArrayType()) { - const ArrayType *ATy = Context.getAsArrayType(T); - Info.Type = Context.getTypeSizeInChars(ATy->getElementType()).getQuantity(); - Info.Length = Info.Size / Info.Type; - } +void Sema::FillInlineAsmIdentifierInfo(Expr *Res, + llvm::InlineAsmIdentifierInfo &Info) { + QualType T = Res->getType(); + Expr::EvalResult Eval; + if (T->isFunctionType() || T->isDependentType()) { + Info.setLabel(Res); + return; + } else if (Res->isRValue()) { + bool Enum = isa(T) && Res->EvaluateAsRValue(Eval, Context); + Enum ? Info.setEnum(Eval.Val.getInt().getSExtValue()) : Info.setLabel(Res); + return; + } + unsigned Size = Context.getTypeSizeInChars(T).getQuantity(); + unsigned Type = Size; + if (const auto *ATy = Context.getAsArrayType(T)) + Type = Context.getTypeSizeInChars(ATy->getElementType()).getQuantity(); + bool IsGlobalLV = false; + if (Res->EvaluateAsLValue(Eval, Context)) + IsGlobalLV = Eval.isGlobalLValue(); + Info.setVar(Res, IsGlobalLV, Size, Type); } ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, - llvm::InlineAsmIdentifierInfo &Info, bool IsUnevaluatedContext) { - Info.clear(); if (IsUnevaluatedContext) PushExpressionEvaluationContext( @@ -662,12 +673,6 @@ return ExprError(); } - fillInlineAsmTypeInfo(Context, T, Info); - - // We can work with the expression as long as it's not an r-value. - if (!Result.get()->isRValue()) - Info.IsVarDecl = true; - return Result; } @@ -741,9 +746,7 @@ ExprResult Sema::LookupInlineAsmVarDeclField(Expr *E, StringRef Member, - llvm::InlineAsmIdentifierInfo &Info, SourceLocation AsmLoc) { - Info.clear(); QualType T = E->getType(); if (T->isDependentType()) { @@ -778,14 +781,6 @@ ExprResult Result = BuildMemberReferenceExpr( E, E->getType(), AsmLoc, /*IsArrow=*/false, CXXScopeSpec(), SourceLocation(), nullptr, FieldResult, nullptr, nullptr); - if (Result.isInvalid()) - return Result; - Info.OpDecl = Result.get(); - - fillInlineAsmTypeInfo(Context, Result.get()->getType(), Info); - - // Fields are "variables" as far as inline assembly is concerned. - Info.IsVarDecl = true; return Result; }