[cfe-commits] r166184 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaStmtAsm.cpp test/CodeGen/ms-inline-asm.c
Chad Rosier
mcrosier at apple.com
Thu Oct 18 08:49:41 PDT 2012
Author: mcrosier
Date: Thu Oct 18 10:49:40 2012
New Revision: 166184
URL: http://llvm.org/viewvc/llvm-project?rev=166184&view=rev
Log:
[ms-inline asm] Move most of the AsmParsing logic in clang back into the MC
layer. Use the new ParseMSInlineAsm() API and add an implementation of the
MCAsmParserSemaCallback interface.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaStmtAsm.cpp
cfe/trunk/test/CodeGen/ms-inline-asm.c
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=166184&r1=166183&r2=166184&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Oct 18 10:49:40 2012
@@ -2601,6 +2601,7 @@
Expr *AsmString, MultiExprArg Clobbers,
SourceLocation RParenLoc);
+ NamedDecl *LookupInlineAsmIdentifier(StringRef Name, SourceLocation Loc);
StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
ArrayRef<Token> AsmToks, SourceLocation EndLoc);
Modified: cfe/trunk/lib/Sema/SemaStmtAsm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAsm.cpp?rev=166184&r1=166183&r2=166184&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmtAsm.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmtAsm.cpp Thu Oct 18 10:49:40 2012
@@ -24,19 +24,12 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCInstPrinter.h"
-#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCTargetAsmParser.h"
-#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
-#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
@@ -367,55 +360,73 @@
return false;
}
-namespace {
-enum AsmOpRewriteKind {
- AOK_Imm,
- AOK_Input,
- AOK_Output
-};
-
-struct AsmOpRewrite {
- AsmOpRewriteKind Kind;
- llvm::SMLoc Loc;
- unsigned Len;
+class MCAsmParserSemaCallbackImpl : public llvm::MCAsmParserSemaCallback {
+ Sema *SemaRef;
public:
- AsmOpRewrite(AsmOpRewriteKind kind, llvm::SMLoc loc, unsigned len)
- : Kind(kind), Loc(loc), Len(len) { }
+ MCAsmParserSemaCallbackImpl(class Sema *Ref) { SemaRef = Ref; }
+ ~MCAsmParserSemaCallbackImpl() {}
+
+ void *LookupInlineAsmIdentifier(StringRef Name, void *SrcLoc,
+ void **IdentifierInfoPtr) {
+ SourceLocation Loc = SourceLocation::getFromPtrEncoding(SrcLoc);
+ NamedDecl *OpDecl = SemaRef->LookupInlineAsmIdentifier(Name, Loc);
+ DeclarationNameInfo NameInfo(OpDecl->getDeclName(), Loc);
+ ExprResult OpExpr = SemaRef->BuildDeclarationNameExpr(CXXScopeSpec(),
+ NameInfo,
+ OpDecl);
+ if (OpExpr.isInvalid())
+ return 0;
+
+ *IdentifierInfoPtr = static_cast<void*>(OpDecl->getIdentifier());
+ return static_cast<void *>(OpExpr.take());
+ }
};
+NamedDecl *Sema::LookupInlineAsmIdentifier(StringRef Name, SourceLocation Loc) {
+ LookupResult Result(*this, &Context.Idents.get(Name), Loc,
+ Sema::LookupOrdinaryName);
+
+ if (!LookupName(Result, getCurScope())) {
+ // If we don't find anything, return null; the AsmParser will assume
+ // it is a label of some sort.
+ return 0;
+ }
+
+ if (!Result.isSingleResult()) {
+ // FIXME: Diagnose result.
+ return 0;
+ }
+
+ NamedDecl *ND = Result.getFoundDecl();
+ if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
+ return ND;
+ }
+
+ // FIXME: Handle other kinds of results? (FieldDecl, etc.)
+ // FIXME: Diagnose if we find something we can't handle, like a typedef.
+ return 0;
}
StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
ArrayRef<Token> AsmToks,SourceLocation EndLoc) {
- SmallVector<IdentifierInfo*, 4> Inputs;
- SmallVector<IdentifierInfo*, 4> Outputs;
SmallVector<IdentifierInfo*, 4> Names;
- SmallVector<std::string, 4> InputConstraints;
- SmallVector<std::string, 4> OutputConstraints;
- SmallVector<StringRef, 4> Constraints;
- unsigned NumOutputs;
- unsigned NumInputs;
- SmallVector<Expr*, 4> InputExprs;
- SmallVector<Expr*, 4> OutputExprs;
+ SmallVector<StringRef, 4> ConstraintRefs;
SmallVector<Expr*, 4> Exprs;
- SmallVector<StringRef, 4> Clobbers;
- std::set<std::string> ClobberRegs;
-
- SmallVector<struct AsmOpRewrite, 4> AsmStrRewrites;
+ SmallVector<StringRef, 4> ClobberRefs;
// Empty asm statements don't need to instantiate the AsmParser, etc.
- if (AsmToks.empty()) {
+ if (AsmToks.empty()) {
StringRef EmptyAsmStr;
MSAsmStmt *NS =
new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true,
/*IsVolatile*/ true, AsmToks, /*NumOutputs*/ 0,
- /*NumInputs*/ 0, Names, Constraints, Exprs, EmptyAsmStr,
- Clobbers, EndLoc);
+ /*NumInputs*/ 0, Names, ConstraintRefs, Exprs,
+ EmptyAsmStr, ClobberRefs, EndLoc);
return Owned(NS);
}
- std::string AsmString;
+ std::string AsmString;
if (buildMSAsmString(*this, AsmLoc, AsmToks, AsmString))
return StmtError();
@@ -443,7 +454,6 @@
Parser(createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));
OwningPtr<llvm::MCTargetAsmParser>
TargetParser(TheTarget->createMCAsmParser(*STI, *Parser));
- Parser->setParsingInlineAsm(true);
// Get the instruction descriptor.
const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo();
@@ -455,152 +465,43 @@
Parser->setTargetParser(*TargetParser.get());
Parser->setParsingInlineAsm(true);
- // Prime the lexer.
- Parser->Lex();
-
- // While we have input, parse each statement.
- unsigned InputIdx = 0;
- unsigned OutputIdx = 0;
- while (Parser->getLexer().isNot(llvm::AsmToken::Eof)) {
- if (Parser->ParseStatement()) {
- // FIXME: The AsmParser should report errors, but we could potentially be
- // more verbose here.
- break;
- }
-
- if (Parser->isInstruction()) {
- const llvm::MCInstrDesc &Desc = MII->get(Parser->getOpcode());
-
- // Build the list of clobbers, outputs and inputs.
- for (unsigned i = 1, e = Parser->getNumParsedOperands(); i != e; ++i) {
- llvm::MCParsedAsmOperand &Operand = Parser->getParsedOperand(i);
-
- // Immediate.
- if (Operand.isImm()) {
- AsmStrRewrites.push_back(AsmOpRewrite(AOK_Imm,
- Operand.getStartLoc(),
- Operand.getNameLen()));
- continue;
- }
-
-
- // Register operand.
- if (Operand.isReg()) {
- unsigned NumDefs = Desc.getNumDefs();
- // Clobber.
- if (NumDefs && Operand.getMCOperandNum() < NumDefs) {
- std::string Reg;
- llvm::raw_string_ostream OS(Reg);
- IP->printRegName(OS, Operand.getReg());
- StringRef Clobber(OS.str());
- if (!Context.getTargetInfo().isValidClobber(Clobber))
- return StmtError(
- Diag(AsmLoc, diag::err_asm_unknown_register_name) << Clobber);
- ClobberRegs.insert(Reg);
- }
- continue;
- }
-
-
- // Expr/Input or Output.
- StringRef Name = Operand.getName();
- if (IdentifierInfo *II = &Context.Idents.get(Name)) {
- CXXScopeSpec SS;
- UnqualifiedId Id;
- SourceLocation Loc;
- Id.setIdentifier(II, AsmLoc);
- ExprResult Result = ActOnIdExpression(getCurScope(), SS, Loc, Id,
- false, false);
- if (!Result.isInvalid()) {
- bool isOutput = (i == 1) && Desc.mayStore();
- if (isOutput) {
- std::string Constraint = "=";
- ++InputIdx;
- Outputs.push_back(II);
- OutputExprs.push_back(Result.take());
- Constraint += Operand.getConstraint().str();
- OutputConstraints.push_back(Constraint);
- AsmStrRewrites.push_back(AsmOpRewrite(AOK_Output,
- Operand.getStartLoc(),
- Operand.getNameLen()));
- } else {
- Inputs.push_back(II);
- InputExprs.push_back(Result.take());
- InputConstraints.push_back(Operand.getConstraint().str());
- AsmStrRewrites.push_back(AsmOpRewrite(AOK_Input,
- Operand.getStartLoc(),
- Operand.getNameLen()));
- }
- }
- }
- }
- Parser->freeParsedOperands();
- }
- }
-
- // Set the number of Outputs and Inputs.
- NumOutputs = Outputs.size();
- NumInputs = Inputs.size();
-
- // Set the unique clobbers.
- for (std::set<std::string>::iterator I = ClobberRegs.begin(),
- E = ClobberRegs.end(); I != E; ++I)
- Clobbers.push_back(*I);
-
- // Merge the various outputs and inputs. Output are expected first.
- Names.resize(NumOutputs + NumInputs);
- Constraints.resize(NumOutputs + NumInputs);
- Exprs.resize(NumOutputs + NumInputs);
- for (unsigned i = 0; i < NumOutputs; ++i) {
- Names[i] = Outputs[i];
- Constraints[i] = OutputConstraints[i];
- Exprs[i] = OutputExprs[i];
- }
- for (unsigned i = 0, j = NumOutputs; i < NumInputs; ++i, ++j) {
- Names[j] = Inputs[i];
- Constraints[j] = InputConstraints[i];
- Exprs[j] = InputExprs[i];
- }
-
- // Build the IR assembly string.
+ unsigned NumOutputs;
+ unsigned NumInputs;
std::string AsmStringIR;
- llvm::raw_string_ostream OS(AsmStringIR);
- const char *Start = AsmString.c_str();
- for (SmallVectorImpl<struct AsmOpRewrite>::iterator I = AsmStrRewrites.begin(),
- E = AsmStrRewrites.end(); I != E; ++I) {
- const char *Loc = (*I).Loc.getPointer();
-
- // Emit everything up to the immediate/expression.
- OS << StringRef(Start, Loc - Start);
-
- // Rewrite expressions in $N notation.
- switch ((*I).Kind) {
- case AOK_Imm:
- OS << Twine("$$") + StringRef(Loc, (*I).Len);
- break;
- case AOK_Input:
- OS << '$';
- OS << InputIdx++;
- break;
- case AOK_Output:
- OS << '$';
- OS << OutputIdx++;
- break;
- }
+ SmallVector<void *, 4> VoidNames;
+ SmallVector<std::string, 4> Constraints;
+ SmallVector<void *, 4> VoidExprs;
+ SmallVector<std::string, 4> Clobbers;
+ MCAsmParserSemaCallbackImpl MCAPSI(this);
+ if (Parser->ParseMSInlineAsm(AsmLoc.getPtrEncoding(), AsmStringIR,
+ NumOutputs, NumInputs, VoidNames, Constraints,
+ VoidExprs, Clobbers, MII, IP, MCAPSI))
+ return StmtError();
- // Skip the original expression.
- Start = Loc + (*I).Len;
+ // Build the vector of clobber StringRefs.
+ unsigned NumClobbers = Clobbers.size();
+ ClobberRefs.resize(NumClobbers);
+ for (unsigned i = 0; i != NumClobbers; ++i)
+ ClobberRefs[i] = StringRef(Clobbers[i]);
+
+ // Recast the void pointers and build the vector of constraint StringRefs.
+ unsigned NumExprs = NumOutputs + NumInputs;
+ assert (VoidNames.size() == NumExprs && "Unexpected number of names!");
+ assert (VoidExprs.size() == NumExprs && "Unexpected number of exprs!");
+ Names.resize(NumExprs);
+ ConstraintRefs.resize(NumExprs);
+ Exprs.resize(NumExprs);
+ for (unsigned i = 0, e = NumExprs; i != e; ++i) {
+ Names[i] = static_cast<IdentifierInfo *>(VoidNames[i]);
+ ConstraintRefs[i] = StringRef(Constraints[i]);
+ Exprs[i] = static_cast<Expr *>(VoidExprs[i]);
}
- // Emit the remainder of the asm string.
- const char *AsmEnd = AsmString.c_str() + AsmString.size();
- if (Start != AsmEnd)
- OS << StringRef(Start, AsmEnd - Start);
- AsmString = OS.str();
+ bool IsSimple = NumExprs > 0;
MSAsmStmt *NS =
- new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true,
- /*IsVolatile*/ true, AsmToks, NumOutputs,
- NumInputs, Names, Constraints, Exprs, AsmString,
- Clobbers, EndLoc);
+ new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple,
+ /*IsVolatile*/ true, AsmToks, NumOutputs, NumInputs,
+ Names, ConstraintRefs, Exprs, AsmStringIR,
+ ClobberRefs, EndLoc);
return Owned(NS);
}
Modified: cfe/trunk/test/CodeGen/ms-inline-asm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-inline-asm.c?rev=166184&r1=166183&r2=166184&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/ms-inline-asm.c (original)
+++ cfe/trunk/test/CodeGen/ms-inline-asm.c Thu Oct 18 10:49:40 2012
@@ -114,3 +114,20 @@
// CHECK: t12
// CHECK: call void asm sideeffect inteldialect "mov eax, $2\0A\09mov $0, eax\0A\09mov eax, $3\0A\09mov $1, eax", "=*m,=*m,*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) nounwind
}
+
+#if 0
+void t13() {
+ unsigned i = 1, j = 2;
+// __asm mov eax, [ebx]
+// __asm mov eax, [4*ecx]
+// __asm mov eax, [4]
+// __asm mov eax, [ebx + 4*ecx]
+// __asm mov eax, [ebx + 4*ecx + 4]
+ __asm mov eax, [i]
+ __asm mov eax, [i + 4*ecx]
+ __asm mov eax, [i + 4*ecx + 4]
+ __asm mov eax, [4*i]
+ __asm mov eax, [ebx + 4*i]
+ __asm mov eax, [ebx + 4*i + 4]
+}
+#endif
More information about the cfe-commits
mailing list