From: Michael Zuckerman Date: Tue, 15 Dec 2015 14:04:18 +0000 (+0000) Subject: [Microsoft][C++] Clang doesn't support a use of "this" pointer inside inline asm X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=980893d5370d3a1ab0fbf928786335b5aef95561;p=clang [Microsoft][C++] Clang doesn't support a use of "this" pointer inside inline asm Clang doesn’t support a use of “this” pointer inside inline asm. When I tried to compile a class or a struct (see example) with an inline asm that contains "this" pointer. Clang returns with an error. This patch fixes that. error: expected unqualified-id For example: ''' struct A { void f() { __asm mov eax, this // error: expected unqualified-id } }; ''' Differential Revision: http://reviews.llvm.org/D15115 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@255645 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index e125b805b2..cc4fa2ec59 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -1696,7 +1696,8 @@ llvm::Value* CodeGenFunction::EmitAsmInput( if (Info.allowsRegister() || !Info.allowsMemory()) if (CodeGenFunction::hasScalarEvaluationKind(InputExpr->getType())) return EmitScalarExpr(InputExpr); - + if (InputExpr->getStmtClass() == Expr::CXXThisExprClass) + return EmitScalarExpr(InputExpr); InputExpr = InputExpr->IgnoreParenNoopCasts(getContext()); LValue Dest = EmitLValue(InputExpr); return EmitAsmInputLValue(Info, Dest, InputExpr->getType(), ConstraintStr, diff --git a/lib/Parse/ParseStmtAsm.cpp b/lib/Parse/ParseStmtAsm.cpp index d3281393f9..f469a064f8 100644 --- a/lib/Parse/ParseStmtAsm.cpp +++ b/lib/Parse/ParseStmtAsm.cpp @@ -215,17 +215,22 @@ ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl &LineToks, // Require an identifier here. SourceLocation TemplateKWLoc; UnqualifiedId Id; - bool Invalid = - ParseUnqualifiedId(SS, - /*EnteringContext=*/false, - /*AllowDestructorName=*/false, - /*AllowConstructorName=*/false, - /*ObjectType=*/ParsedType(), TemplateKWLoc, Id); - - // Perform the lookup. - ExprResult Result = Actions.LookupInlineAsmIdentifier( - SS, TemplateKWLoc, Id, Info, IsUnevaluatedContext); - + bool Invalid = true; + ExprResult Result; + if (Tok.is(tok::kw_this)) { + Result = ParseCXXThis(); + Invalid = false; + } else { + Invalid = + ParseUnqualifiedId(SS, + /*EnteringContext=*/false, + /*AllowDestructorName=*/false, + /*AllowConstructorName=*/false, + /*ObjectType=*/ParsedType(), TemplateKWLoc, Id); + // Perform the lookup. + Result = Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id, Info, + IsUnevaluatedContext); + } // While the next two tokens are 'period' 'identifier', repeatedly parse it as // a field access. We have to avoid consuming assembler directives that look // like '.' 'else'. diff --git a/test/CodeGen/ms_this.cpp b/test/CodeGen/ms_this.cpp new file mode 100644 index 0000000000..10cd52ffc6 --- /dev/null +++ b/test/CodeGen/ms_this.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -fasm-blocks -emit-llvm %s -o - | FileCheck %s +class t1 { +public: + double a; + void runc(); +}; + +class t2 { +public: + double a; + void runc(); +}; + +void t2::runc() { + double num = 0; + __asm { + mov rax,[this] + //CHECK: %this.addr = alloca %class.t2* + //CHECK: call void asm sideeffect inteldialect "mov rax,qword ptr $1{{.*}}%class.t2* %this1 + mov rbx,[rax] + mov num, rbx + }; +} + +void t1::runc() { + double num = 0; + __asm { + mov rax,[this] + //CHECK: %this.addr = alloca %class.t1* + //CHECK: call void asm sideeffect inteldialect "mov rax,qword ptr $1{{.*}}%class.t1* %this1 + mov rbx,[rax] + mov num, rbx + }; +} + +struct s { + int a; + void func() { + __asm mov rax, [this] + //CHECK: %this.addr = alloca %struct.s* + //CHECK: call void asm sideeffect inteldialect "mov rax, qword ptr $0{{.*}}%struct.s* %this1 + } +} f3; + +int main() { + f3.func(); + f3.a=1; + return 0; +}