[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