]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/lib/Sema/SemaStmtAsm.cpp
MFC r244628:
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / lib / Sema / SemaStmtAsm.cpp
1 //===--- SemaStmtAsm.cpp - Semantic Analysis for Asm Statements -----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file implements semantic analysis for inline asm statements.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "clang/Sema/SemaInternal.h"
15 #include "clang/Sema/Scope.h"
16 #include "clang/Sema/ScopeInfo.h"
17 #include "clang/Sema/Initialization.h"
18 #include "clang/Sema/Lookup.h"
19 #include "clang/AST/RecordLayout.h"
20 #include "clang/AST/TypeLoc.h"
21 #include "clang/Lex/Preprocessor.h"
22 #include "clang/Basic/TargetInfo.h"
23 #include "llvm/ADT/ArrayRef.h"
24 #include "llvm/ADT/BitVector.h"
25 #include "llvm/ADT/SmallString.h"
26 #include "llvm/MC/MCAsmInfo.h"
27 #include "llvm/MC/MCContext.h"
28 #include "llvm/MC/MCObjectFileInfo.h"
29 #include "llvm/MC/MCRegisterInfo.h"
30 #include "llvm/MC/MCStreamer.h"
31 #include "llvm/MC/MCSubtargetInfo.h"
32 #include "llvm/MC/MCTargetAsmParser.h"
33 #include "llvm/MC/MCParser/MCAsmParser.h"
34 #include "llvm/Support/SourceMgr.h"
35 #include "llvm/Support/TargetRegistry.h"
36 #include "llvm/Support/TargetSelect.h"
37 using namespace clang;
38 using namespace sema;
39
40 /// CheckAsmLValue - GNU C has an extremely ugly extension whereby they silently
41 /// ignore "noop" casts in places where an lvalue is required by an inline asm.
42 /// We emulate this behavior when -fheinous-gnu-extensions is specified, but
43 /// provide a strong guidance to not use it.
44 ///
45 /// This method checks to see if the argument is an acceptable l-value and
46 /// returns false if it is a case we can handle.
47 static bool CheckAsmLValue(const Expr *E, Sema &S) {
48   // Type dependent expressions will be checked during instantiation.
49   if (E->isTypeDependent())
50     return false;
51
52   if (E->isLValue())
53     return false;  // Cool, this is an lvalue.
54
55   // Okay, this is not an lvalue, but perhaps it is the result of a cast that we
56   // are supposed to allow.
57   const Expr *E2 = E->IgnoreParenNoopCasts(S.Context);
58   if (E != E2 && E2->isLValue()) {
59     if (!S.getLangOpts().HeinousExtensions)
60       S.Diag(E2->getLocStart(), diag::err_invalid_asm_cast_lvalue)
61         << E->getSourceRange();
62     else
63       S.Diag(E2->getLocStart(), diag::warn_invalid_asm_cast_lvalue)
64         << E->getSourceRange();
65     // Accept, even if we emitted an error diagnostic.
66     return false;
67   }
68
69   // None of the above, just randomly invalid non-lvalue.
70   return true;
71 }
72
73 /// isOperandMentioned - Return true if the specified operand # is mentioned
74 /// anywhere in the decomposed asm string.
75 static bool isOperandMentioned(unsigned OpNo,
76                          ArrayRef<GCCAsmStmt::AsmStringPiece> AsmStrPieces) {
77   for (unsigned p = 0, e = AsmStrPieces.size(); p != e; ++p) {
78     const GCCAsmStmt::AsmStringPiece &Piece = AsmStrPieces[p];
79     if (!Piece.isOperand()) continue;
80
81     // If this is a reference to the input and if the input was the smaller
82     // one, then we have to reject this asm.
83     if (Piece.getOperandNo() == OpNo)
84       return true;
85   }
86   return false;
87 }
88
89 StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
90                                  bool IsVolatile, unsigned NumOutputs,
91                                  unsigned NumInputs, IdentifierInfo **Names,
92                                  MultiExprArg constraints, MultiExprArg exprs,
93                                  Expr *asmString, MultiExprArg clobbers,
94                                  SourceLocation RParenLoc) {
95   unsigned NumClobbers = clobbers.size();
96   StringLiteral **Constraints =
97     reinterpret_cast<StringLiteral**>(constraints.data());
98   Expr **Exprs = exprs.data();
99   StringLiteral *AsmString = cast<StringLiteral>(asmString);
100   StringLiteral **Clobbers = reinterpret_cast<StringLiteral**>(clobbers.data());
101
102   SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos;
103
104   // The parser verifies that there is a string literal here.
105   if (!AsmString->isAscii())
106     return StmtError(Diag(AsmString->getLocStart(),diag::err_asm_wide_character)
107       << AsmString->getSourceRange());
108
109   for (unsigned i = 0; i != NumOutputs; i++) {
110     StringLiteral *Literal = Constraints[i];
111     if (!Literal->isAscii())
112       return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
113         << Literal->getSourceRange());
114
115     StringRef OutputName;
116     if (Names[i])
117       OutputName = Names[i]->getName();
118
119     TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName);
120     if (!Context.getTargetInfo().validateOutputConstraint(Info))
121       return StmtError(Diag(Literal->getLocStart(),
122                             diag::err_asm_invalid_output_constraint)
123                        << Info.getConstraintStr());
124
125     // Check that the output exprs are valid lvalues.
126     Expr *OutputExpr = Exprs[i];
127     if (CheckAsmLValue(OutputExpr, *this)) {
128       return StmtError(Diag(OutputExpr->getLocStart(),
129                   diag::err_asm_invalid_lvalue_in_output)
130         << OutputExpr->getSourceRange());
131     }
132
133     OutputConstraintInfos.push_back(Info);
134   }
135
136   SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos;
137
138   for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) {
139     StringLiteral *Literal = Constraints[i];
140     if (!Literal->isAscii())
141       return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
142         << Literal->getSourceRange());
143
144     StringRef InputName;
145     if (Names[i])
146       InputName = Names[i]->getName();
147
148     TargetInfo::ConstraintInfo Info(Literal->getString(), InputName);
149     if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos.data(),
150                                                 NumOutputs, Info)) {
151       return StmtError(Diag(Literal->getLocStart(),
152                             diag::err_asm_invalid_input_constraint)
153                        << Info.getConstraintStr());
154     }
155
156     Expr *InputExpr = Exprs[i];
157
158     // Only allow void types for memory constraints.
159     if (Info.allowsMemory() && !Info.allowsRegister()) {
160       if (CheckAsmLValue(InputExpr, *this))
161         return StmtError(Diag(InputExpr->getLocStart(),
162                               diag::err_asm_invalid_lvalue_in_input)
163                          << Info.getConstraintStr()
164                          << InputExpr->getSourceRange());
165     }
166
167     if (Info.allowsRegister()) {
168       if (InputExpr->getType()->isVoidType()) {
169         return StmtError(Diag(InputExpr->getLocStart(),
170                               diag::err_asm_invalid_type_in_input)
171           << InputExpr->getType() << Info.getConstraintStr()
172           << InputExpr->getSourceRange());
173       }
174     }
175
176     ExprResult Result = DefaultFunctionArrayLvalueConversion(Exprs[i]);
177     if (Result.isInvalid())
178       return StmtError();
179
180     Exprs[i] = Result.take();
181     InputConstraintInfos.push_back(Info);
182   }
183
184   // Check that the clobbers are valid.
185   for (unsigned i = 0; i != NumClobbers; i++) {
186     StringLiteral *Literal = Clobbers[i];
187     if (!Literal->isAscii())
188       return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
189         << Literal->getSourceRange());
190
191     StringRef Clobber = Literal->getString();
192
193     if (!Context.getTargetInfo().isValidClobber(Clobber))
194       return StmtError(Diag(Literal->getLocStart(),
195                   diag::err_asm_unknown_register_name) << Clobber);
196   }
197
198   GCCAsmStmt *NS =
199     new (Context) GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs,
200                              NumInputs, Names, Constraints, Exprs, AsmString,
201                              NumClobbers, Clobbers, RParenLoc);
202   // Validate the asm string, ensuring it makes sense given the operands we
203   // have.
204   SmallVector<GCCAsmStmt::AsmStringPiece, 8> Pieces;
205   unsigned DiagOffs;
206   if (unsigned DiagID = NS->AnalyzeAsmString(Pieces, Context, DiagOffs)) {
207     Diag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID)
208            << AsmString->getSourceRange();
209     return StmtError();
210   }
211
212   // Validate constraints and modifiers.
213   for (unsigned i = 0, e = Pieces.size(); i != e; ++i) {
214     GCCAsmStmt::AsmStringPiece &Piece = Pieces[i];
215     if (!Piece.isOperand()) continue;
216
217     // Look for the correct constraint index.
218     unsigned Idx = 0;
219     unsigned ConstraintIdx = 0;
220     for (unsigned i = 0, e = NS->getNumOutputs(); i != e; ++i, ++ConstraintIdx) {
221       TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i];
222       if (Idx == Piece.getOperandNo())
223         break;
224       ++Idx;
225
226       if (Info.isReadWrite()) {
227         if (Idx == Piece.getOperandNo())
228           break;
229         ++Idx;
230       }
231     }
232
233     for (unsigned i = 0, e = NS->getNumInputs(); i != e; ++i, ++ConstraintIdx) {
234       TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
235       if (Idx == Piece.getOperandNo())
236         break;
237       ++Idx;
238
239       if (Info.isReadWrite()) {
240         if (Idx == Piece.getOperandNo())
241           break;
242         ++Idx;
243       }
244     }
245
246     // Now that we have the right indexes go ahead and check.
247     StringLiteral *Literal = Constraints[ConstraintIdx];
248     const Type *Ty = Exprs[ConstraintIdx]->getType().getTypePtr();
249     if (Ty->isDependentType() || Ty->isIncompleteType())
250       continue;
251
252     unsigned Size = Context.getTypeSize(Ty);
253     if (!Context.getTargetInfo()
254           .validateConstraintModifier(Literal->getString(), Piece.getModifier(),
255                                       Size))
256       Diag(Exprs[ConstraintIdx]->getLocStart(),
257            diag::warn_asm_mismatched_size_modifier);
258   }
259
260   // Validate tied input operands for type mismatches.
261   for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) {
262     TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
263
264     // If this is a tied constraint, verify that the output and input have
265     // either exactly the same type, or that they are int/ptr operands with the
266     // same size (int/long, int*/long, are ok etc).
267     if (!Info.hasTiedOperand()) continue;
268
269     unsigned TiedTo = Info.getTiedOperand();
270     unsigned InputOpNo = i+NumOutputs;
271     Expr *OutputExpr = Exprs[TiedTo];
272     Expr *InputExpr = Exprs[InputOpNo];
273
274     if (OutputExpr->isTypeDependent() || InputExpr->isTypeDependent())
275       continue;
276
277     QualType InTy = InputExpr->getType();
278     QualType OutTy = OutputExpr->getType();
279     if (Context.hasSameType(InTy, OutTy))
280       continue;  // All types can be tied to themselves.
281
282     // Decide if the input and output are in the same domain (integer/ptr or
283     // floating point.
284     enum AsmDomain {
285       AD_Int, AD_FP, AD_Other
286     } InputDomain, OutputDomain;
287
288     if (InTy->isIntegerType() || InTy->isPointerType())
289       InputDomain = AD_Int;
290     else if (InTy->isRealFloatingType())
291       InputDomain = AD_FP;
292     else
293       InputDomain = AD_Other;
294
295     if (OutTy->isIntegerType() || OutTy->isPointerType())
296       OutputDomain = AD_Int;
297     else if (OutTy->isRealFloatingType())
298       OutputDomain = AD_FP;
299     else
300       OutputDomain = AD_Other;
301
302     // They are ok if they are the same size and in the same domain.  This
303     // allows tying things like:
304     //   void* to int*
305     //   void* to int            if they are the same size.
306     //   double to long double   if they are the same size.
307     //
308     uint64_t OutSize = Context.getTypeSize(OutTy);
309     uint64_t InSize = Context.getTypeSize(InTy);
310     if (OutSize == InSize && InputDomain == OutputDomain &&
311         InputDomain != AD_Other)
312       continue;
313
314     // If the smaller input/output operand is not mentioned in the asm string,
315     // then we can promote the smaller one to a larger input and the asm string
316     // won't notice.
317     bool SmallerValueMentioned = false;
318
319     // If this is a reference to the input and if the input was the smaller
320     // one, then we have to reject this asm.
321     if (isOperandMentioned(InputOpNo, Pieces)) {
322       // This is a use in the asm string of the smaller operand.  Since we
323       // codegen this by promoting to a wider value, the asm will get printed
324       // "wrong".
325       SmallerValueMentioned |= InSize < OutSize;
326     }
327     if (isOperandMentioned(TiedTo, Pieces)) {
328       // If this is a reference to the output, and if the output is the larger
329       // value, then it's ok because we'll promote the input to the larger type.
330       SmallerValueMentioned |= OutSize < InSize;
331     }
332
333     // If the smaller value wasn't mentioned in the asm string, and if the
334     // output was a register, just extend the shorter one to the size of the
335     // larger one.
336     if (!SmallerValueMentioned && InputDomain != AD_Other &&
337         OutputConstraintInfos[TiedTo].allowsRegister())
338       continue;
339
340     // Either both of the operands were mentioned or the smaller one was
341     // mentioned.  One more special case that we'll allow: if the tied input is
342     // integer, unmentioned, and is a constant, then we'll allow truncating it
343     // down to the size of the destination.
344     if (InputDomain == AD_Int && OutputDomain == AD_Int &&
345         !isOperandMentioned(InputOpNo, Pieces) &&
346         InputExpr->isEvaluatable(Context)) {
347       CastKind castKind =
348         (OutTy->isBooleanType() ? CK_IntegralToBoolean : CK_IntegralCast);
349       InputExpr = ImpCastExprToType(InputExpr, OutTy, castKind).take();
350       Exprs[InputOpNo] = InputExpr;
351       NS->setInputExpr(i, InputExpr);
352       continue;
353     }
354
355     Diag(InputExpr->getLocStart(),
356          diag::err_asm_tying_incompatible_types)
357       << InTy << OutTy << OutputExpr->getSourceRange()
358       << InputExpr->getSourceRange();
359     return StmtError();
360   }
361
362   return Owned(NS);
363 }
364
365 // getSpelling - Get the spelling of the AsmTok token.
366 static StringRef getSpelling(Sema &SemaRef, Token AsmTok) {
367   StringRef Asm;
368   SmallString<512> TokenBuf;
369   TokenBuf.resize(512);
370   bool StringInvalid = false;
371   Asm = SemaRef.PP.getSpelling(AsmTok, TokenBuf, &StringInvalid);
372   assert (!StringInvalid && "Expected valid string!");
373   return Asm;
374 }
375
376 // Build the inline assembly string.  Returns true on error.
377 static bool buildMSAsmString(Sema &SemaRef,
378                              SourceLocation AsmLoc,
379                              ArrayRef<Token> AsmToks,
380                              llvm::SmallVectorImpl<unsigned> &TokOffsets,
381                              std::string &AsmString) {
382   assert (!AsmToks.empty() && "Didn't expect an empty AsmToks!");
383
384   SmallString<512> Asm;
385   for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) {
386     bool isNewAsm = ((i == 0) ||
387                      AsmToks[i].isAtStartOfLine() ||
388                      AsmToks[i].is(tok::kw_asm));
389     if (isNewAsm) {
390       if (i != 0)
391         Asm += "\n\t";
392
393       if (AsmToks[i].is(tok::kw_asm)) {
394         i++; // Skip __asm
395         if (i == e) {
396           SemaRef.Diag(AsmLoc, diag::err_asm_empty);
397           return true;
398         }
399
400       }
401     }
402
403     if (i && AsmToks[i].hasLeadingSpace() && !isNewAsm)
404       Asm += ' ';
405
406     StringRef Spelling = getSpelling(SemaRef, AsmToks[i]);
407     Asm += Spelling;
408     TokOffsets.push_back(Asm.size());
409   }
410   AsmString = Asm.str();
411   return false;
412 }
413
414 namespace {
415
416 class MCAsmParserSemaCallbackImpl : public llvm::MCAsmParserSemaCallback {
417   Sema &SemaRef;
418   SourceLocation AsmLoc;
419   ArrayRef<Token> AsmToks;
420   ArrayRef<unsigned> TokOffsets;
421
422 public:
423   MCAsmParserSemaCallbackImpl(Sema &Ref, SourceLocation Loc,
424                               ArrayRef<Token> Toks,
425                               ArrayRef<unsigned> Offsets)
426     : SemaRef(Ref), AsmLoc(Loc), AsmToks(Toks), TokOffsets(Offsets) { }
427   ~MCAsmParserSemaCallbackImpl() {}
428
429   void *LookupInlineAsmIdentifier(StringRef Name, void *SrcLoc, unsigned &Size){
430     SourceLocation Loc = SourceLocation::getFromPtrEncoding(SrcLoc);
431     NamedDecl *OpDecl = SemaRef.LookupInlineAsmIdentifier(Name, Loc, Size);
432     return static_cast<void *>(OpDecl);
433   }
434
435   bool LookupInlineAsmField(StringRef Base, StringRef Member,
436                             unsigned &Offset) {
437     return SemaRef.LookupInlineAsmField(Base, Member, Offset, AsmLoc);
438   }
439
440   static void MSAsmDiagHandlerCallback(const llvm::SMDiagnostic &D,
441                                        void *Context) {
442     ((MCAsmParserSemaCallbackImpl*)Context)->MSAsmDiagHandler(D);
443   }
444   void MSAsmDiagHandler(const llvm::SMDiagnostic &D) {
445     // Compute an offset into the inline asm buffer.
446     // FIXME: This isn't right if .macro is involved (but hopefully, no
447     // real-world code does that).
448     const llvm::SourceMgr &LSM = *D.getSourceMgr();
449     const llvm::MemoryBuffer *LBuf =
450     LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
451     unsigned Offset = D.getLoc().getPointer()  - LBuf->getBufferStart();
452
453     // Figure out which token that offset points into.
454     const unsigned *OffsetPtr =
455         std::lower_bound(TokOffsets.begin(), TokOffsets.end(), Offset);
456     unsigned TokIndex = OffsetPtr - TokOffsets.begin();
457
458     // If we come up with an answer which seems sane, use it; otherwise,
459     // just point at the __asm keyword.
460     // FIXME: Assert the answer is sane once we handle .macro correctly.
461     SourceLocation Loc = AsmLoc;
462     if (TokIndex < AsmToks.size()) {
463       const Token *Tok = &AsmToks[TokIndex];
464       Loc = Tok->getLocation();
465       Loc = Loc.getLocWithOffset(Offset - (*OffsetPtr - Tok->getLength()));
466     }
467     SemaRef.Diag(Loc, diag::err_inline_ms_asm_parsing) << D.getMessage();
468   }
469 };
470
471 }
472
473 NamedDecl *Sema::LookupInlineAsmIdentifier(StringRef Name, SourceLocation Loc,
474                                            unsigned &Size) {
475   Size = 0;
476   LookupResult Result(*this, &Context.Idents.get(Name), Loc,
477                       Sema::LookupOrdinaryName);
478
479   if (!LookupName(Result, getCurScope())) {
480     // If we don't find anything, return null; the AsmParser will assume
481     // it is a label of some sort.
482     return 0;
483   }
484
485   if (!Result.isSingleResult()) {
486     // FIXME: Diagnose result.
487     return 0;
488   }
489
490   NamedDecl *ND = Result.getFoundDecl();
491   if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
492     if (VarDecl *Var = dyn_cast<VarDecl>(ND))
493       Size = Context.getTypeInfo(Var->getType()).first;
494
495     return ND;
496   }
497
498   // FIXME: Handle other kinds of results? (FieldDecl, etc.)
499   // FIXME: Diagnose if we find something we can't handle, like a typedef.
500   return 0;
501 }
502
503 bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member,
504                                 unsigned &Offset, SourceLocation AsmLoc) {
505   Offset = 0;
506   LookupResult BaseResult(*this, &Context.Idents.get(Base), SourceLocation(),
507                           LookupOrdinaryName);
508
509   if (!LookupName(BaseResult, getCurScope()))
510     return true;
511
512   if (!BaseResult.isSingleResult())
513     return true;
514
515   NamedDecl *FoundDecl = BaseResult.getFoundDecl();
516   const RecordType *RT = 0;
517   if (VarDecl *VD = dyn_cast<VarDecl>(FoundDecl)) {
518     RT = VD->getType()->getAs<RecordType>();
519   } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(FoundDecl)) {
520     RT = TD->getUnderlyingType()->getAs<RecordType>();
521   }
522   if (!RT)
523     return true;
524
525   if (RequireCompleteType(AsmLoc, QualType(RT, 0), 0))
526     return true;
527
528   LookupResult FieldResult(*this, &Context.Idents.get(Member), SourceLocation(),
529                            LookupMemberName);
530
531   if (!LookupQualifiedName(FieldResult, RT->getDecl()))
532     return true;
533
534   // FIXME: Handle IndirectFieldDecl?
535   FieldDecl *FD = dyn_cast<FieldDecl>(FieldResult.getFoundDecl());
536   if (!FD)
537     return true;
538
539   const ASTRecordLayout &RL = Context.getASTRecordLayout(RT->getDecl());
540   unsigned i = FD->getFieldIndex();
541   CharUnits Result = Context.toCharUnitsFromBits(RL.getFieldOffset(i));
542   Offset = (unsigned)Result.getQuantity();
543
544   return false;
545 }
546
547 StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
548                                 ArrayRef<Token> AsmToks,SourceLocation EndLoc) {
549   SmallVector<IdentifierInfo*, 4> Names;
550   SmallVector<StringRef, 4> ConstraintRefs;
551   SmallVector<Expr*, 4> Exprs;
552   SmallVector<StringRef, 4> ClobberRefs;
553
554   // Empty asm statements don't need to instantiate the AsmParser, etc.
555   if (AsmToks.empty()) {
556     StringRef EmptyAsmStr;
557     MSAsmStmt *NS =
558       new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true,
559                               /*IsVolatile*/ true, AsmToks, /*NumOutputs*/ 0,
560                               /*NumInputs*/ 0, Names, ConstraintRefs, Exprs,
561                               EmptyAsmStr, ClobberRefs, EndLoc);
562     return Owned(NS);
563   }
564
565   std::string AsmString;
566   llvm::SmallVector<unsigned, 8> TokOffsets;
567   if (buildMSAsmString(*this, AsmLoc, AsmToks, TokOffsets, AsmString))
568     return StmtError();
569
570   // Get the target specific parser.
571   std::string Error;
572   const std::string &TT = Context.getTargetInfo().getTriple().getTriple();
573   const llvm::Target *TheTarget(llvm::TargetRegistry::lookupTarget(TT, Error));
574
575   OwningPtr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TT));
576   OwningPtr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));
577   OwningPtr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo());
578   OwningPtr<llvm::MCSubtargetInfo>
579     STI(TheTarget->createMCSubtargetInfo(TT, "", ""));
580
581   llvm::SourceMgr SrcMgr;
582   llvm::MCContext Ctx(*MAI, *MRI, MOFI.get(), &SrcMgr);
583   llvm::MemoryBuffer *Buffer =
584     llvm::MemoryBuffer::getMemBuffer(AsmString, "<inline asm>");
585
586   // Tell SrcMgr about this buffer, which is what the parser will pick up.
587   SrcMgr.AddNewSourceBuffer(Buffer, llvm::SMLoc());
588
589   OwningPtr<llvm::MCStreamer> Str(createNullStreamer(Ctx));
590   OwningPtr<llvm::MCAsmParser>
591     Parser(createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));
592   OwningPtr<llvm::MCTargetAsmParser>
593     TargetParser(TheTarget->createMCAsmParser(*STI, *Parser));
594
595   // Get the instruction descriptor.
596   const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo(); 
597   llvm::MCInstPrinter *IP =
598     TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI);
599
600   // Change to the Intel dialect.
601   Parser->setAssemblerDialect(1);
602   Parser->setTargetParser(*TargetParser.get());
603   Parser->setParsingInlineAsm(true);
604   TargetParser->setParsingInlineAsm(true);
605
606   MCAsmParserSemaCallbackImpl MCAPSI(*this, AsmLoc, AsmToks, TokOffsets);
607   TargetParser->setSemaCallback(&MCAPSI);
608   SrcMgr.setDiagHandler(MCAsmParserSemaCallbackImpl::MSAsmDiagHandlerCallback,
609                         &MCAPSI);
610
611   unsigned NumOutputs;
612   unsigned NumInputs;
613   std::string AsmStringIR;
614   SmallVector<std::pair<void *, bool>, 4> OpDecls;
615   SmallVector<std::string, 4> Constraints;
616   SmallVector<std::string, 4> Clobbers;
617   if (Parser->ParseMSInlineAsm(AsmLoc.getPtrEncoding(), AsmStringIR,
618                                NumOutputs, NumInputs, OpDecls, Constraints,
619                                Clobbers, MII, IP, MCAPSI))
620     return StmtError();
621
622   // Build the vector of clobber StringRefs.
623   unsigned NumClobbers = Clobbers.size();
624   ClobberRefs.resize(NumClobbers);
625   for (unsigned i = 0; i != NumClobbers; ++i)
626     ClobberRefs[i] = StringRef(Clobbers[i]);
627
628   // Recast the void pointers and build the vector of constraint StringRefs.
629   unsigned NumExprs = NumOutputs + NumInputs;
630   Names.resize(NumExprs);
631   ConstraintRefs.resize(NumExprs);
632   Exprs.resize(NumExprs);
633   for (unsigned i = 0, e = NumExprs; i != e; ++i) {
634     NamedDecl *OpDecl = static_cast<NamedDecl *>(OpDecls[i].first);
635     if (!OpDecl)
636       return StmtError();
637
638     DeclarationNameInfo NameInfo(OpDecl->getDeclName(), AsmLoc);
639     ExprResult OpExpr = BuildDeclarationNameExpr(CXXScopeSpec(), NameInfo,
640                                                  OpDecl);
641     if (OpExpr.isInvalid())
642       return StmtError();
643
644     // Need offset of variable.
645     if (OpDecls[i].second)
646       OpExpr = BuildUnaryOp(getCurScope(), AsmLoc, clang::UO_AddrOf,
647                             OpExpr.take());
648
649     Names[i] = OpDecl->getIdentifier();
650     ConstraintRefs[i] = StringRef(Constraints[i]);
651     Exprs[i] = OpExpr.take();
652   }
653
654   bool IsSimple = NumExprs > 0;
655   MSAsmStmt *NS =
656     new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple,
657                             /*IsVolatile*/ true, AsmToks, NumOutputs, NumInputs,
658                             Names, ConstraintRefs, Exprs, AsmStringIR,
659                             ClobberRefs, EndLoc);
660   return Owned(NS);
661 }