Ejemplo n.º 1
0
void IdentifierResolver::iterator::incrementSlowCase() {
  NamedDecl *D = **this;
//@@
  assert(!D->getDeclName().getAsIdentifierInfo() ||
         !D->getDeclName().getAsIdentifierInfo()->isMetaGenerated());
//@@
  void *InfoPtr = D->getDeclName().getFETokenInfo<void>();
  assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
  IdDeclInfo *Info = toIdDeclInfo(InfoPtr);

  BaseIter I = getIterator();
  if (I != Info->decls_begin())
    *this = iterator(I-1);
  else // No more decls.
    *this = iterator();
}
Ejemplo n.º 2
0
void DeclContext::removeDecl(Decl *D) {
  assert(D->getLexicalDeclContext() == this &&
         "decl being removed from non-lexical context");
  assert((D->NextInContextAndBits.getPointer() || D == LastDecl) &&
         "decl is not in decls list");

  // Remove D from the decl chain.  This is O(n) but hopefully rare.
  if (D == FirstDecl) {
    if (D == LastDecl)
      FirstDecl = LastDecl = 0;
    else
      FirstDecl = D->NextInContextAndBits.getPointer();
  } else {
    for (Decl *I = FirstDecl; true; I = I->NextInContextAndBits.getPointer()) {
      assert(I && "decl not found in linked list");
      if (I->NextInContextAndBits.getPointer() == D) {
        I->NextInContextAndBits.setPointer(D->NextInContextAndBits.getPointer());
        if (D == LastDecl) LastDecl = I;
        break;
      }
    }
  }
  
  // Mark that D is no longer in the decl chain.
  D->NextInContextAndBits.setPointer(0);

  // Remove D from the lookup table if necessary.
  if (isa<NamedDecl>(D)) {
    NamedDecl *ND = cast<NamedDecl>(D);

    // Remove only decls that have a name or registered in the lookup.
    if (!ND->getDeclName() || ND->isHidden()) return;

    StoredDeclsMap *Map = D->getDeclContext()->getPrimaryContext()->LookupPtr.getPointer();
    if (!Map) return;

    StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
#ifndef NDEBUG
    assert(Pos != Map->end() && "no lookup entry for decl");
#endif
    if (Pos != Map->end()
        && (Pos->second.getAsVector() || Pos->second.getAsDecl() == ND)
       )
      Pos->second.remove(ND);
  }
}
Ejemplo n.º 3
0
static void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
                              const EffectiveContext &EC,
                              AccessTarget &Entity) {
  const CXXRecordDecl *NamingClass = Entity.getNamingClass();
  const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
  NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0);

  S.Diag(Loc, Entity.getDiag())
    << (Entity.getAccess() == AS_protected)
    << (D ? D->getDeclName() : DeclarationName())
    << S.Context.getTypeDeclType(NamingClass)
    << S.Context.getTypeDeclType(DeclaringClass);
  DiagnoseAccessPath(S, EC, Entity);
}
Ejemplo n.º 4
0
bool HasNameMatcher::matchesNodeUnqualified(const NamedDecl &Node) const {
  assert(UseUnqualifiedMatch);
  if (Node.getIdentifier()) {
    // Simple name.
    return Name == Node.getName();
  }
  if (Node.getDeclName()) {
    // Name needs to be constructed.
    llvm::SmallString<128> NodeName;
    llvm::raw_svector_ostream OS(NodeName);
    Node.printName(OS);
    return Name == OS.str();
  }
  return false;
}
Ejemplo n.º 5
0
  ///\brief Checks for clashing names when trying to extract a declaration.
  ///
  ///\returns true if there is another declaration with the same name
  bool DeclExtractor::CheckForClashingNames(
                                  const llvm::SmallVector<NamedDecl*, 4>& Decls,
                                            DeclContext* DC, Scope* S) {
    for (size_t i = 0; i < Decls.size(); ++i) {
      NamedDecl* ND = Decls[i];

      if (TagDecl* TD = dyn_cast<TagDecl>(ND)) {
        LookupResult Previous(*m_Sema, ND->getDeclName(), ND->getLocation(),
                              Sema::LookupTagName, Sema::ForRedeclaration
                              );

        m_Sema->LookupName(Previous, S);

        // There is no function diagnosing the redeclaration of tags (eg. enums).
        // So either we have to do it by hand or we can call the top-most
        // function that does the check. Currently the top-most clang function
        // doing the checks creates an AST node, which we don't want.
        if (!CheckTagDeclaration(TD, Previous))
          return true;
      }
      else if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
        LookupResult Previous(*m_Sema, ND->getDeclName(), ND->getLocation(),
                              Sema::LookupOrdinaryName, Sema::ForRedeclaration
                              );

        m_Sema->LookupName(Previous, S);
        m_Sema->CheckVariableDeclaration(VD, Previous);
        if (VD->isInvalidDecl())
          return true;
        // This var decl will likely get referenced later; claim that it's used.
        VD->setIsUsed();
      }
    }

    return false;
  }
Ejemplo n.º 6
0
void DeclContext::removeDecl(Decl *D) {
  assert(D->getLexicalDeclContext() == this &&
         "decl being removed from non-lexical context");
  assert((D->NextDeclInContext || D == LastDecl) &&
         "decl is not in decls list");

  // Remove D from the decl chain.  This is O(n) but hopefully rare.
  if (D == FirstDecl) {
    if (D == LastDecl)
      FirstDecl = LastDecl = 0;
    else
      FirstDecl = D->NextDeclInContext;
  } else {
    for (Decl *I = FirstDecl; true; I = I->NextDeclInContext) {
      assert(I && "decl not found in linked list");
      if (I->NextDeclInContext == D) {
        I->NextDeclInContext = D->NextDeclInContext;
        if (D == LastDecl) LastDecl = I;
        break;
      }
    }
  }
  
  // Mark that D is no longer in the decl chain.
  D->NextDeclInContext = 0;

  // Remove D from the lookup table if necessary.
  if (isa<NamedDecl>(D)) {
    NamedDecl *ND = cast<NamedDecl>(D);

    StoredDeclsMap *Map = getPrimaryContext()->LookupPtr;
    if (!Map) return;

    StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
    assert(Pos != Map->end() && "no lookup entry for decl");
    Pos->second.remove(ND);
  }
}
Ejemplo n.º 7
0
void TemplateArgument::print(const PrintingPolicy &Policy, 
                             raw_ostream &Out) const {
  switch (getKind()) {
  case Null:
    Out << "<no value>";
    break;
    
  case Type: {
    PrintingPolicy SubPolicy(Policy);
    SubPolicy.SuppressStrongLifetime = true;
    getAsType().print(Out, SubPolicy);
    break;
  }
    
  case Declaration: {
    NamedDecl *ND = cast<NamedDecl>(getAsDecl());
    Out << '&';
    if (ND->getDeclName()) {
      // FIXME: distinguish between pointer and reference args?
      ND->printQualifiedName(Out);
    } else {
      Out << "<anonymous>";
    }
    break;
  }

  case NullPtr:
    Out << "nullptr";
    break;

  case Template:
    getAsTemplate().print(Out, Policy);
    break;

  case TemplateExpansion:
    getAsTemplateOrTemplatePattern().print(Out, Policy);
    Out << "...";
    break;
      
  case Integral: {
    printIntegral(*this, Out);
    break;
  }
    
  case Expression:
    getAsExpr()->printPretty(Out, 0, Policy);
    break;
    
  case Pack:
    Out << "<";
    bool First = true;
    for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end();
         P != PEnd; ++P) {
      if (First)
        First = false;
      else
        Out << ", ";
      
      P->print(Policy, Out);
    }
    Out << ">";
    break;        
  }
}
Ejemplo n.º 8
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);
}
// Adapted from tools\clang\lib\AST\TemplateBase.cpp TemplateArgument::print
void printTemplateArgument(raw_ostream &out, const PrintingPolicy &policy, TemplateArgument const &arg, bool qualifyNames)
{
    switch (arg.getKind()) {
    case TemplateArgument::Null:
        out << "(no value)";
        break;

    case TemplateArgument::Type: {
        PrintingPolicy SubPolicy(policy);
        SubPolicy.SuppressStrongLifetime = true;
        arg.getAsType().print(out, SubPolicy);
        break;
    }

    case TemplateArgument::Declaration: {
        NamedDecl *ND = cast<NamedDecl>(arg.getAsDecl());
        out << '&';
        if (ND->getDeclName()) {
            // FIXME: distinguish between pointer and reference args?
            ND->printQualifiedName(out);
        }
        else {
            out << "(anonymous)";
        }
        break;
    }

    case TemplateArgument::NullPtr:
        out << "nullptr";
        break;

    case TemplateArgument::Template:
        // Orig: arg.getAsTemplate().print(out, policy);
    {
        auto templateName = arg.getAsTemplate();
        printTemplateName(out, policy, templateName, qualifyNames);
        break;
    }

    case TemplateArgument::TemplateExpansion:
        arg.getAsTemplateOrTemplatePattern().print(out, policy);
        out << "...";
        break;

    case TemplateArgument::Integral: {
        printIntegral(arg, out, policy);
        break;
    }

    case TemplateArgument::Expression:
        arg.getAsExpr()->printPretty(out, nullptr, policy);
        break;

    case TemplateArgument::Pack:
        out << "<";
        bool First = true;
        for (const auto &P : arg.pack_elements()) {
            if (First)
                First = false;
            else
                out << ", ";

            P.print(policy, out);
        }
        out << ">";
        break;
    }
}