Ejemplo n.º 1
0
CXCursor cxcursor::MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
                                     CXTranslationUnit TU) {
    assert(Type && TU && "Invalid arguments!");
    void *RawLoc = Loc.getPtrEncoding();
    CXCursor C = { CXCursor_TypeRef, 0, { Type, RawLoc, TU } };
    return C;
}
Ejemplo n.º 2
0
CXCursor cxcursor::MakeMacroExpansionCursor(MacroDefinition *MI,
        SourceLocation Loc,
        CXTranslationUnit TU) {
    assert(Loc.isValid());
    CXCursor C = { CXCursor_MacroExpansion, 0, { MI, Loc.getPtrEncoding(), TU } };
    return C;
}
Ejemplo n.º 3
0
CXCursor cxcursor::MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
                                      CXTranslationUnit TU) {

    assert(Label && TU && "Invalid arguments!");
    void *RawLoc = Loc.getPtrEncoding();
    CXCursor C = { CXCursor_LabelRef, 0, { Label, RawLoc, TU } };
    return C;
}
Ejemplo n.º 4
0
CXCursor cxcursor::MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc,
                                       CXTranslationUnit TU) {

    assert(Field && TU && "Invalid arguments!");
    void *RawLoc = Loc.getPtrEncoding();
    CXCursor C = { CXCursor_MemberRef, 0, { Field, RawLoc, TU } };
    return C;
}
Ejemplo n.º 5
0
CXCursor cxcursor::MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
        CXTranslationUnit TU) {

    assert(Var && TU && "Invalid arguments!");
    void *RawLoc = Loc.getPtrEncoding();
    CXCursor C = { CXCursor_VariableRef, 0, { Var, RawLoc, TU } };
    return C;
}
Ejemplo n.º 6
0
CXCursor cxcursor::MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
        SourceLocation Loc,
        CXTranslationUnit TU) {
    assert(Proto && TU && "Invalid arguments!");
    void *RawLoc = Loc.getPtrEncoding();
    CXCursor C = { CXCursor_ObjCProtocolRef, 0, { Proto, RawLoc, TU } };
    return C;
}
Ejemplo n.º 7
0
CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
        SourceLocation Loc,
        CXTranslationUnit TU) {
    assert(Super && TU && "Invalid arguments!");
    void *RawLoc = Loc.getPtrEncoding();
    CXCursor C = { CXCursor_ObjCSuperClassRef, 0, { Super, RawLoc, TU } };
    return C;
}
Ejemplo n.º 8
0
CXCursor cxcursor::MakeCursorNamespaceRef(const NamedDecl *NS,
        SourceLocation Loc,
        CXTranslationUnit TU) {

    assert(NS && (isa<NamespaceDecl>(NS) || isa<NamespaceAliasDecl>(NS)) && TU &&
           "Invalid arguments!");
    void *RawLoc = Loc.getPtrEncoding();
    CXCursor C = { CXCursor_NamespaceRef, 0, { NS, RawLoc, TU } };
    return C;
}
Ejemplo n.º 9
0
CXCursor cxcursor::MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
        SourceLocation Loc,
        CXTranslationUnit TU) {
    // 'Class' can be null for invalid code.
    if (!Class)
        return MakeCXCursorInvalid(CXCursor_InvalidCode);
    assert(TU && "Invalid arguments!");
    void *RawLoc = Loc.getPtrEncoding();
    CXCursor C = { CXCursor_ObjCClassRef, 0, { Class, RawLoc, TU } };
    return C;
}
Ejemplo n.º 10
0
CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name,
        SourceLocation Loc,
        CXTranslationUnit TU) {
    assert(Name.getAsOverloadedTemplate() && TU && "Invalid arguments!");
    void *RawLoc = Loc.getPtrEncoding();
    OverloadedDeclRefStorage Storage(Name.getAsOverloadedTemplate());
    CXCursor C = {
        CXCursor_OverloadedDeclRef, 0,
        { Storage.getOpaqueValue(), RawLoc, TU }
    };
    return C;
}
Ejemplo n.º 11
0
bool EmptyStructToIntRewriteVisitor::VisitRecordTypeLoc(RecordTypeLoc RTLoc)
{
  const RecordDecl *RD = RTLoc.getDecl();
  if (RD->getCanonicalDecl() == ConsumerInstance->TheRecordDecl) {
    SourceLocation LocStart = RTLoc.getLocStart();
    void *LocPtr = LocStart.getPtrEncoding();
    if (ConsumerInstance->VisitedLocs.count(LocPtr))
      return true;
    ConsumerInstance->VisitedLocs.insert(LocPtr);

    // handle a special case -
    // struct S1 {
    //   struct { } S;
    // };
    const IdentifierInfo *TypeId = RTLoc.getType().getBaseTypeIdentifier();
    if (!TypeId)
      return true;
    ConsumerInstance->RewriteHelper->replaceRecordType(RTLoc, "int");
    ConsumerInstance->Rewritten = true;
  }
  return true;
}
Ejemplo n.º 12
0
StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
                                ArrayRef<Token> AsmToks,SourceLocation EndLoc) {
  SmallVector<IdentifierInfo*, 4> Names;
  SmallVector<StringRef, 4> ConstraintRefs;
  SmallVector<Expr*, 4> Exprs;
  SmallVector<StringRef, 4> ClobberRefs;

  llvm::Triple TheTriple = Context.getTargetInfo().getTriple();
  llvm::Triple::ArchType ArchTy = TheTriple.getArch();
  bool UnsupportedArch = ArchTy != llvm::Triple::x86 &&
    ArchTy != llvm::Triple::x86_64;
  if (UnsupportedArch)
    Diag(AsmLoc, diag::err_msasm_unsupported_arch) << TheTriple.getArchName();
    
  // Empty asm statements don't need to instantiate the AsmParser, etc.
  if (UnsupportedArch || AsmToks.empty()) {
    StringRef EmptyAsmStr;
    MSAsmStmt *NS =
      new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true,
                              /*IsVolatile*/ true, AsmToks, /*NumOutputs*/ 0,
                              /*NumInputs*/ 0, Names, ConstraintRefs, Exprs,
                              EmptyAsmStr, ClobberRefs, EndLoc);
    return Owned(NS);
  }

  std::string AsmString;
  SmallVector<unsigned, 8> TokOffsets;
  if (buildMSAsmString(*this, AsmLoc, AsmToks, TokOffsets, AsmString))
    return StmtError();

  // Get the target specific parser.
  std::string Error;
  const std::string &TT = TheTriple.getTriple();
  const llvm::Target *TheTarget(llvm::TargetRegistry::lookupTarget(TT, Error));

  OwningPtr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TT));
  OwningPtr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));
  OwningPtr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo());
  OwningPtr<llvm::MCSubtargetInfo>
    STI(TheTarget->createMCSubtargetInfo(TT, "", ""));

  llvm::SourceMgr SrcMgr;
  llvm::MCContext Ctx(*MAI, *MRI, MOFI.get(), &SrcMgr);
  llvm::MemoryBuffer *Buffer =
    llvm::MemoryBuffer::getMemBuffer(AsmString, "<MS inline asm>");

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  SrcMgr.AddNewSourceBuffer(Buffer, llvm::SMLoc());

  OwningPtr<llvm::MCStreamer> Str(createNullStreamer(Ctx));
  OwningPtr<llvm::MCAsmParser>
    Parser(createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));
  OwningPtr<llvm::MCTargetAsmParser>
    TargetParser(TheTarget->createMCAsmParser(*STI, *Parser));

  // Get the instruction descriptor.
  const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo(); 
  llvm::MCInstPrinter *IP =
    TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI);

  // Change to the Intel dialect.
  Parser->setAssemblerDialect(1);
  Parser->setTargetParser(*TargetParser.get());
  Parser->setParsingInlineAsm(true);
  TargetParser->setParsingInlineAsm(true);

  MCAsmParserSemaCallbackImpl MCAPSI(*this, AsmLoc, AsmToks, TokOffsets);
  TargetParser->setSemaCallback(&MCAPSI);
  SrcMgr.setDiagHandler(MCAsmParserSemaCallbackImpl::MSAsmDiagHandlerCallback,
                        &MCAPSI);

  unsigned NumOutputs;
  unsigned NumInputs;
  std::string AsmStringIR;
  SmallVector<std::pair<void *, bool>, 4> OpDecls;
  SmallVector<std::string, 4> Constraints;
  SmallVector<std::string, 4> Clobbers;
  if (Parser->parseMSInlineAsm(AsmLoc.getPtrEncoding(), AsmStringIR,
                               NumOutputs, NumInputs, OpDecls, Constraints,
                               Clobbers, MII, IP, MCAPSI))
    return StmtError();

  // 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;
  Names.resize(NumExprs);
  ConstraintRefs.resize(NumExprs);
  Exprs.resize(NumExprs);
  for (unsigned i = 0, e = NumExprs; i != e; ++i) {
    NamedDecl *OpDecl = static_cast<NamedDecl *>(OpDecls[i].first);
    if (!OpDecl)
      return StmtError();

    DeclarationNameInfo NameInfo(OpDecl->getDeclName(), AsmLoc);
    ExprResult OpExpr = BuildDeclarationNameExpr(CXXScopeSpec(), NameInfo,
                                                 OpDecl);
    if (OpExpr.isInvalid())
      return StmtError();

    // Need address of variable.
    if (OpDecls[i].second)
      OpExpr = BuildUnaryOp(getCurScope(), AsmLoc, clang::UO_AddrOf,
                            OpExpr.take());

    Names[i] = OpDecl->getIdentifier();
    ConstraintRefs[i] = StringRef(Constraints[i]);
    Exprs[i] = OpExpr.take();
  }

  bool IsSimple = NumExprs > 0;
  MSAsmStmt *NS =
    new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple,
                            /*IsVolatile*/ true, AsmToks, NumOutputs, NumInputs,
                            Names, ConstraintRefs, Exprs, AsmStringIR,
                            ClobberRefs, EndLoc);
  return Owned(NS);
}
Ejemplo n.º 13
0
/// ParseMicrosoftAsmStatement. When -fms-extensions/-fasm-blocks is enabled,
/// this routine is called to collect the tokens for an MS asm statement.
///
/// [MS]  ms-asm-statement:
///         ms-asm-block
///         ms-asm-block ms-asm-statement
///
/// [MS]  ms-asm-block:
///         '__asm' ms-asm-line '\n'
///         '__asm' '{' ms-asm-instruction-block[opt] '}' ';'[opt]
///
/// [MS]  ms-asm-instruction-block
///         ms-asm-line
///         ms-asm-line '\n' ms-asm-instruction-block
///
StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
  SourceManager &SrcMgr = PP.getSourceManager();
  SourceLocation EndLoc = AsmLoc;
  SmallVector<Token, 4> AsmToks;

  bool SingleLineMode = true;
  unsigned BraceNesting = 0;
  unsigned short savedBraceCount = BraceCount;
  bool InAsmComment = false;
  FileID FID;
  unsigned LineNo = 0;
  unsigned NumTokensRead = 0;
  SmallVector<SourceLocation, 4> LBraceLocs;
  bool SkippedStartOfLine = false;

  if (Tok.is(tok::l_brace)) {
    // Braced inline asm: consume the opening brace.
    SingleLineMode = false;
    BraceNesting = 1;
    EndLoc = ConsumeBrace();
    LBraceLocs.push_back(EndLoc);
    ++NumTokensRead;
  } else {
    // Single-line inline asm; compute which line it is on.
    std::pair<FileID, unsigned> ExpAsmLoc =
        SrcMgr.getDecomposedExpansionLoc(EndLoc);
    FID = ExpAsmLoc.first;
    LineNo = SrcMgr.getLineNumber(FID, ExpAsmLoc.second);
    LBraceLocs.push_back(SourceLocation());
  }

  SourceLocation TokLoc = Tok.getLocation();
  do {
    // If we hit EOF, we're done, period.
    if (isEofOrEom())
      break;

    if (!InAsmComment && Tok.is(tok::l_brace)) {
      // Consume the opening brace.
      SkippedStartOfLine = Tok.isAtStartOfLine();
      EndLoc = ConsumeBrace();
      BraceNesting++;
      LBraceLocs.push_back(EndLoc);
      TokLoc = Tok.getLocation();
      ++NumTokensRead;
      continue;
    } else if (!InAsmComment && Tok.is(tok::semi)) {
      // A semicolon in an asm is the start of a comment.
      InAsmComment = true;
      if (!SingleLineMode) {
        // Compute which line the comment is on.
        std::pair<FileID, unsigned> ExpSemiLoc =
            SrcMgr.getDecomposedExpansionLoc(TokLoc);
        FID = ExpSemiLoc.first;
        LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second);
      }
    } else if (SingleLineMode || InAsmComment) {
      // If end-of-line is significant, check whether this token is on a
      // new line.
      std::pair<FileID, unsigned> ExpLoc =
          SrcMgr.getDecomposedExpansionLoc(TokLoc);
      if (ExpLoc.first != FID ||
          SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) {
        // If this is a single-line __asm, we're done, except if the next
        // line begins with an __asm too, in which case we finish a comment
        // if needed and then keep processing the next line as a single
        // line __asm.
        bool isAsm = Tok.is(tok::kw_asm);
        if (SingleLineMode && !isAsm)
          break;
        // We're no longer in a comment.
        InAsmComment = false;
        if (isAsm) {
          LineNo = SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second);
          SkippedStartOfLine = Tok.isAtStartOfLine();
        }
      } else if (!InAsmComment && Tok.is(tok::r_brace)) {
        // In MSVC mode, braces only participate in brace matching and
        // separating the asm statements.  This is an intentional
        // departure from the Apple gcc behavior.
        if (!BraceNesting)
          break;
      }
    }
    if (!InAsmComment && BraceNesting && Tok.is(tok::r_brace) &&
        BraceCount == (savedBraceCount + BraceNesting)) {
      // Consume the closing brace.
      SkippedStartOfLine = Tok.isAtStartOfLine();
      EndLoc = ConsumeBrace();
      BraceNesting--;
      // Finish if all of the opened braces in the inline asm section were
      // consumed.
      if (BraceNesting == 0 && !SingleLineMode)
        break;
      else {
        LBraceLocs.pop_back();
        TokLoc = Tok.getLocation();
        ++NumTokensRead;
        continue;
      }
    }

    // Consume the next token; make sure we don't modify the brace count etc.
    // if we are in a comment.
    EndLoc = TokLoc;
    if (InAsmComment)
      PP.Lex(Tok);
    else {
      // Set the token as the start of line if we skipped the original start
      // of line token in case it was a nested brace.
      if (SkippedStartOfLine)
        Tok.setFlag(Token::StartOfLine);
      AsmToks.push_back(Tok);
      ConsumeAnyToken();
    }
    TokLoc = Tok.getLocation();
    ++NumTokensRead;
    SkippedStartOfLine = false;
  } while (1);

  if (BraceNesting && BraceCount != savedBraceCount) {
    // __asm without closing brace (this can happen at EOF).
    for (unsigned i = 0; i < BraceNesting; ++i) {
      Diag(Tok, diag::err_expected) << tok::r_brace;
      Diag(LBraceLocs.back(), diag::note_matching) << tok::l_brace;
      LBraceLocs.pop_back();
    }
    return StmtError();
  } else if (NumTokensRead == 0) {
    // Empty __asm.
    Diag(Tok, diag::err_expected) << tok::l_brace;
    return StmtError();
  }

  // Okay, prepare to use MC to parse the assembly.
  SmallVector<StringRef, 4> ConstraintRefs;
  SmallVector<Expr *, 4> Exprs;
  SmallVector<StringRef, 4> ClobberRefs;

  // We need an actual supported target.
  const llvm::Triple &TheTriple = Actions.Context.getTargetInfo().getTriple();
  llvm::Triple::ArchType ArchTy = TheTriple.getArch();
  const std::string &TT = TheTriple.getTriple();
  const llvm::Target *TheTarget = nullptr;
  bool UnsupportedArch =
      (ArchTy != llvm::Triple::x86 && ArchTy != llvm::Triple::x86_64);
  if (UnsupportedArch) {
    Diag(AsmLoc, diag::err_msasm_unsupported_arch) << TheTriple.getArchName();
  } else {
    std::string Error;
    TheTarget = llvm::TargetRegistry::lookupTarget(TT, Error);
    if (!TheTarget)
      Diag(AsmLoc, diag::err_msasm_unable_to_create_target) << Error;
  }

  assert(!LBraceLocs.empty() && "Should have at least one location here");

  // If we don't support assembly, or the assembly is empty, we don't
  // need to instantiate the AsmParser, etc.
  if (!TheTarget || AsmToks.empty()) {
    return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLocs[0], AsmToks, StringRef(),
                                  /*NumOutputs*/ 0, /*NumInputs*/ 0,
                                  ConstraintRefs, ClobberRefs, Exprs, EndLoc);
  }

  // Expand the tokens into a string buffer.
  SmallString<512> AsmString;
  SmallVector<unsigned, 8> TokOffsets;
  if (buildMSAsmString(PP, AsmLoc, AsmToks, TokOffsets, AsmString))
    return StmtError();

  std::unique_ptr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));
  std::unique_ptr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TT));
  // Get the instruction descriptor.
  std::unique_ptr<llvm::MCInstrInfo> MII(TheTarget->createMCInstrInfo());
  std::unique_ptr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo());
  std::unique_ptr<llvm::MCSubtargetInfo> STI(
      TheTarget->createMCSubtargetInfo(TT, "", ""));

  llvm::SourceMgr TempSrcMgr;
  llvm::MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &TempSrcMgr);
  MOFI->InitMCObjectFileInfo(TheTriple, llvm::Reloc::Default,
                             llvm::CodeModel::Default, Ctx);
  std::unique_ptr<llvm::MemoryBuffer> Buffer =
      llvm::MemoryBuffer::getMemBuffer(AsmString, "<MS inline asm>");

  // Tell SrcMgr about this buffer, which is what the parser will pick up.
  TempSrcMgr.AddNewSourceBuffer(std::move(Buffer), llvm::SMLoc());

  std::unique_ptr<llvm::MCStreamer> Str(createNullStreamer(Ctx));
  std::unique_ptr<llvm::MCAsmParser> Parser(
      createMCAsmParser(TempSrcMgr, Ctx, *Str.get(), *MAI));

  // FIXME: init MCOptions from sanitizer flags here.
  llvm::MCTargetOptions MCOptions;
  std::unique_ptr<llvm::MCTargetAsmParser> TargetParser(
      TheTarget->createMCAsmParser(*STI, *Parser, *MII, MCOptions));

  std::unique_ptr<llvm::MCInstPrinter> IP(
      TheTarget->createMCInstPrinter(llvm::Triple(TT), 1, *MAI, *MII, *MRI));

  // Change to the Intel dialect.
  Parser->setAssemblerDialect(1);
  Parser->setTargetParser(*TargetParser.get());
  Parser->setParsingInlineAsm(true);
  TargetParser->setParsingInlineAsm(true);

  ClangAsmParserCallback Callback(*this, AsmLoc, AsmString, AsmToks,
                                  TokOffsets);
  TargetParser->setSemaCallback(&Callback);
  TempSrcMgr.setDiagHandler(ClangAsmParserCallback::DiagHandlerCallback,
                            &Callback);

  unsigned NumOutputs;
  unsigned NumInputs;
  std::string AsmStringIR;
  SmallVector<std::pair<void *, bool>, 4> OpExprs;
  SmallVector<std::string, 4> Constraints;
  SmallVector<std::string, 4> Clobbers;
  if (Parser->parseMSInlineAsm(AsmLoc.getPtrEncoding(), AsmStringIR, NumOutputs,
                               NumInputs, OpExprs, Constraints, Clobbers,
                               MII.get(), IP.get(), Callback))
    return StmtError();

  // Filter out "fpsw".  Clang doesn't accept it, and it always lists flags and
  // fpsr as clobbers.
  auto End = std::remove(Clobbers.begin(), Clobbers.end(), "fpsw");
  Clobbers.erase(End, Clobbers.end());

  // Build the vector of clobber StringRefs.
  ClobberRefs.insert(ClobberRefs.end(), Clobbers.begin(), Clobbers.end());

  // Recast the void pointers and build the vector of constraint StringRefs.
  unsigned NumExprs = NumOutputs + NumInputs;
  ConstraintRefs.resize(NumExprs);
  Exprs.resize(NumExprs);
  for (unsigned i = 0, e = NumExprs; i != e; ++i) {
    Expr *OpExpr = static_cast<Expr *>(OpExprs[i].first);
    if (!OpExpr)
      return StmtError();

    // Need address of variable.
    if (OpExprs[i].second)
      OpExpr =
          Actions.BuildUnaryOp(getCurScope(), AsmLoc, UO_AddrOf, OpExpr).get();

    ConstraintRefs[i] = StringRef(Constraints[i]);
    Exprs[i] = OpExpr;
  }

  // FIXME: We should be passing source locations for better diagnostics.
  return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLocs[0], AsmToks, AsmStringIR,
                                NumOutputs, NumInputs, ConstraintRefs,
                                ClobberRefs, Exprs, EndLoc);
}