Exemplo n.º 1
0
CustomTypeAnnotation::AnnotationReason
CustomTypeAnnotation::tmplArgAnnotationReason(ArrayRef<TemplateArgument> Args) {
  for (const TemplateArgument &Arg : Args) {
    if (Arg.getKind() == TemplateArgument::Type) {
      QualType Type = Arg.getAsType();
      if (hasEffectiveAnnotation(Type)) {
        AnnotationReason Reason = {Type, RK_TemplateInherited, nullptr, ""};
        return Reason;
      }
    } else if (Arg.getKind() == TemplateArgument::Pack) {
      AnnotationReason Reason = tmplArgAnnotationReason(Arg.getPackAsArray());
      if (Reason.Kind != RK_None) {
        return Reason;
      }
    }
  }

  AnnotationReason Reason = {QualType(), RK_None, nullptr, ""};
  return Reason;
}
Exemplo n.º 2
0
bool CheckAllocationsInFunctionVisitor::VisitCallExpr(CallExpr* callExpr)
{
    // Check callExpr for AllocateArray
    auto callee = callExpr->getDirectCallee();
    if (callExpr->getNumArgs() == 3 &&
        callee &&
        callee->getName().equals("AllocateArray"))
    {
        VisitAllocate(
            [=]() { return callExpr->getArg(0); },
            [=]() { return callExpr->getArg(1); },
            [=]()
            {
                auto retType = callExpr->getCallReturnType(_mainVisitor->getContext());
                return QualType(retType->getAs<PointerType>()->getPointeeType());
            }
        );
    }

    return true;
}
Exemplo n.º 3
0
void DynTypedNode::print(llvm::raw_ostream &OS,
                         const PrintingPolicy &PP) const {
  if (const TemplateArgument *TA = get<TemplateArgument>())
    TA->print(PP, OS);
  else if (const NestedNameSpecifier *NNS = get<NestedNameSpecifier>())
    NNS->print(OS, PP);
  else if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
    NNSL->getNestedNameSpecifier()->print(OS, PP);
  else if (const QualType *QT = get<QualType>())
    QT->print(OS, PP);
  else if (const TypeLoc *TL = get<TypeLoc>())
    TL->getType().print(OS, PP);
  else if (const Decl *D = get<Decl>())
    D->print(OS, PP);
  else if (const Stmt *S = get<Stmt>())
    S->printPretty(OS, nullptr, PP);
  else if (const Type *T = get<Type>())
    QualType(T, 0).print(OS, PP);
  else
    OS << "Unable to print values of type " << NodeKind.asStringRef() << "\n";
}
Exemplo n.º 4
0
CustomTypeAnnotation::AnnotationReason
CustomTypeAnnotation::directAnnotationReason(QualType T) {
  if (const TagDecl *D = T->getAsTagDecl()) {
    if (hasCustomAnnotation(D, Spelling)) {
      AnnotationReason Reason = {T, RK_Direct, nullptr, ""};
      return Reason;
    }

    std::string ImplAnnotReason = getImplicitReason(D);
    if (!ImplAnnotReason.empty()) {
      AnnotationReason Reason = {T, RK_Implicit, nullptr, ImplAnnotReason};
      return Reason;
    }
  }

  // Check if we have a cached answer
  void *Key = T.getAsOpaquePtr();
  ReasonCache::iterator Cached = Cache.find(T.getAsOpaquePtr());
  if (Cached != Cache.end()) {
    return Cached->second;
  }

  // Check if we have a type which we can recurse into
  if (const clang::ArrayType *Array = T->getAsArrayTypeUnsafe()) {
    if (hasEffectiveAnnotation(Array->getElementType())) {
      AnnotationReason Reason = {Array->getElementType(), RK_ArrayElement,
                                 nullptr, ""};
      Cache[Key] = Reason;
      return Reason;
    }
  }

  // Recurse into Base classes
  if (const CXXRecordDecl *Declaration = T->getAsCXXRecordDecl()) {
    if (Declaration->hasDefinition()) {
      Declaration = Declaration->getDefinition();

      for (const CXXBaseSpecifier &Base : Declaration->bases()) {
        if (hasEffectiveAnnotation(Base.getType())) {
          AnnotationReason Reason = {Base.getType(), RK_BaseClass, nullptr, ""};
          Cache[Key] = Reason;
          return Reason;
        }
      }

      // Recurse into members
      for (const FieldDecl *Field : Declaration->fields()) {
        if (hasEffectiveAnnotation(Field->getType())) {
          AnnotationReason Reason = {Field->getType(), RK_Field, Field, ""};
          Cache[Key] = Reason;
          return Reason;
        }
      }

      // Recurse into template arguments if the annotation
      // MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS is present
      if (hasCustomAnnotation(
              Declaration, "moz_inherit_type_annotations_from_template_args")) {
        const ClassTemplateSpecializationDecl *Spec =
            dyn_cast<ClassTemplateSpecializationDecl>(Declaration);
        if (Spec) {
          const TemplateArgumentList &Args = Spec->getTemplateArgs();

          AnnotationReason Reason = tmplArgAnnotationReason(Args.asArray());
          if (Reason.Kind != RK_None) {
            Cache[Key] = Reason;
            return Reason;
          }
        }
      }
    }
  }

  AnnotationReason Reason = {QualType(), RK_None, nullptr, ""};
  Cache[Key] = Reason;
  return Reason;
}
Exemplo n.º 5
0
int CDaoNamespace::Generate( CDaoNamespace *outer )
{
	header = "";
	source = "";
	source2 = "";
	source3 = "";
	onload = "";
	onload2 = "";
	onload3 = "";
	if( unsupported ) return 0;

	bool isCpp = module->compiler->getPreprocessor().getLangOpts().CPlusPlus;
	int i, n, retcode = 0;
	for(i=0, n=usertypes.size(); i<n; i++) retcode |= usertypes[i]->Generate();
	for(i=0, n=functions.size(); i<n; i++){
		CDaoFunction *func = functions[i];
		if( func->generated || func->excluded ) continue;
		retcode |= func->Generate();
	}
#if 0
	map<string,int> check;
	for(i=0, n=usertypes.size(); i<n; i++){
		CDaoUserType *ut = usertypes[i];
		if( check.find( ut->qname ) != check.end() ) ut->isRedundant = true;
		if( ut->isRedundant || ut->IsFromRequiredModules() ) continue;
		check[ut->qname] = 1;
	}
#endif

	header = "";
	source = module->MakeSourceCodes( functions, this );
	//source += module->MakeSourceCodes( usertypes, this );
	//source2 = module->MakeSource2Codes( usertypes );
	//source3 = module->MakeSource3Codes( usertypes );

	if( nsdecl ){
		string this_name = varname;
		string outer_name = outer ? outer->varname : "ns";
		string qname = nsdecl->getQualifiedNameAsString();
		string name = nsdecl->getNameAsString();

		outer_name = cdao_qname_to_idname( outer_name );
		if( outer == NULL || outer->nsdecl == NULL ){
			header += "using namespace " + name + ";\n";
			if( name == "std" ) name = "_std";
			if( name == "io" ) name = "_io";
			onload += "\tDaoNamespace *" + this_name + " = DaoVmSpace_GetNamespace( ";
			onload += "vms, \"" + name + "\" );\n";
			onload2 += "\tDaoNamespace_AddConstValue( ns, \"" + name + "\", (DaoValue*) " + this_name + " );\n";
		}else{
			header += "using namespace " + qname + ";\n";
			onload += "\tDaoNamespace *" + this_name + " = DaoNamespace_GetNamespace( ";
			onload += outer_name + ", \"" + name + "\" );\n";
		}
		if( enums.size() || variables.size() || isCpp /* for constant true and false */ ){
			source += module->MakeConstNumber( enums, variables, qname, isCpp );
			onload2 += "\tDaoNamespace_AddConstNumbers( " + this_name;
			onload2 += ", dao_" + this_name + "_Nums );\n";
		}
		onload3 += module->MakeConstStruct( variables, this_name, qname );
	}else{
		if( enums.size() || variables.size() ){
			source += module->MakeConstNumber( enums, variables, "", isCpp );
			onload2 += "\tDaoNamespace_AddConstNumbers( ns, dao__Nums );\n";
		}else if( this == & module->topLevelScope && module->numericConsts.size() ){
			source += module->MakeConstNumber( enums, variables, "", isCpp );
			onload2 += "\tDaoNamespace_AddConstNumbers( ns, dao__Nums );\n";
		}
		onload3 += module->MakeConstStruct( variables, "ns", "" );
	}
	//header += module->MakeHeaderCodes( usertypes );

	onload3 += module->MakeOnLoadCodes( functions, this );
	//onload3 += module->MakeOnLoad2Codes( usertypes );
	for(i=0, n=namespaces.size(); i<n; i++){
		retcode |= namespaces[i]->Generate( this );
		header += namespaces[i]->header;
		source += namespaces[i]->source;
		//source2 += namespaces[i]->source2;
		//source3 += namespaces[i]->source3;
		onload += namespaces[i]->onload;
		onload2 += namespaces[i]->onload2;
		onload3 += namespaces[i]->onload3;
	}
	//onload2 += module->MakeOnLoadCodes( this );

#if 0
	string code = "\tDaoNamespace_DefineType( " + varname + ", \"";
	for(i=0, n=usertypes.size(); i<n; i++){
		CDaoUserType *ut = usertypes[i];
		if( ut->isRedundant || ut->IsFromRequiredModules() ) continue;
		if( dyn_cast<ClassTemplateSpecializationDecl>( ut->decl ) == NULL ) continue;
		QualType qtype = QualType( ut->decl->getTypeForDecl(), 0 ).getCanonicalType();
		string qname = normalize_type_name( qtype.getAsString() );
		string name = cdao_remove_type_scopes( qname );
		string dname = cdao_make_dao_template_type_name( qname );
		string dname2 = cdao_make_dao_template_type_name( ut->name2 );
		if( name != ut->name2 ){
			outs() << ut->qname << " " << ut->name2 << " " << name << "\n";
			onload2 += code + dname + "\", \"" + dname2 + "\" );\n";
		}
	}
#endif
	return retcode;
}
Exemplo n.º 6
0
void MainVisitor::ProcessUnbarrieredFields(
    CXXRecordDecl* recordDecl, const PushFieldType& pushFieldType)
{
    std::string typeName = recordDecl->getQualifiedNameAsString();
    if (typeName == "Memory::WriteBarrierPtr")
    {
        return;  // Skip WriteBarrierPtr itself
    }

    const auto& sourceMgr = _compilerInstance.getSourceManager();
    DiagnosticsEngine& diagEngine = _context.getDiagnostics();
    const unsigned diagID = diagEngine.getCustomDiagID(
        DiagnosticsEngine::Error,
        "Unbarriered field, see "
        "https://github.com/microsoft/ChakraCore/wiki/Software-Write-Barrier#coding-rules");

    for (auto field : recordDecl->fields())
    {
        const QualType qualType = field->getType();
        string fieldTypeName = qualType.getAsString();
        string fieldName = field->getNameAsString();

        if (StartsWith(fieldTypeName, "WriteBarrierPtr<") || // WriteBarrierPtr fields
            Contains(fieldTypeName, "_no_write_barrier_policy, ")) // FieldNoBarrier
        {
            continue; // skip
        }

        // If an annotated field type is struct/class/union (RecordType), the
        // field type in turn should likely be annoatated.
        if (fieldTypeName.back() != '*'  // not "... *"
            &&
            (
                StartsWith(fieldTypeName, "typename WriteBarrierFieldTypeTraits") ||
                StartsWith(fieldTypeName, "WriteBarrierFieldTypeTraits") ||
                StartsWith(fieldTypeName, "const typename WriteBarrierFieldTypeTraits") ||
                StartsWith(fieldTypeName, "const WriteBarrierFieldTypeTraits") ||
                fieldName.length() == 0  // anonymous union/struct
            ))
        {
            auto originalType = qualType->getUnqualifiedDesugaredType();
            if (auto arrayType = dyn_cast<ArrayType>(originalType))
            {
                originalType = arrayType->getElementType()->getUnqualifiedDesugaredType();
            }

            string originalTypeName = QualType(originalType, 0).getAsString();
            if (isa<RecordType>(originalType) &&
                !StartsWith(originalTypeName, "class Memory::WriteBarrierPtr<"))
            {
                if (pushFieldType(originalType))
                {
                    Log::outs() << "Queue field type: " << originalTypeName
                        << " (" << typeName << "::" << fieldName << ")\n";
                }
            }
        }
        else
        {
            SourceLocation location = field->getLocStart();
            if (this->_fix)
            {
                const char* begin = sourceMgr.getCharacterData(location);
                const char* end = begin;

                if (MatchType(fieldTypeName, begin, &end))
                {
                    _rewriter.ReplaceText(
                        location, end - begin,
                        GetFieldTypeAnnotation(qualType) + string(begin, end) +
                             (*end == ' ' ? ")" : ") "));
                    _fixed = true;
                    continue;
                }

                Log::errs() << "Fail to fix: " << fieldTypeName << " "
                            << fieldName << "\n";
            }

            diagEngine.Report(location, diagID);
        }
    }
}
Exemplo n.º 7
0
RangeExpr::RangeExpr(ExprClass Class, SourceLocation Loc,
                     Expr *First, Expr *Second)
  : Expr(Class, QualType(), Loc), E1(First), E2(Second) {
}
Exemplo n.º 8
0
/// \brief Return the fully qualified type, including fully-qualified
/// versions of any template parameters.
QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx) {
  // In case of myType* we need to strip the pointer first, fully
  // qualify and attach the pointer once again.
  if (isa<PointerType>(QT.getTypePtr())) {
    // Get the qualifiers.
    Qualifiers Quals = QT.getQualifiers();
    QT = getFullyQualifiedType(QT->getPointeeType(), Ctx);
    QT = Ctx.getPointerType(QT);
    // Add back the qualifiers.
    QT = Ctx.getQualifiedType(QT, Quals);
    return QT;
  }

  // In case of myType& we need to strip the reference first, fully
  // qualify and attach the reference once again.
  if (isa<ReferenceType>(QT.getTypePtr())) {
    // Get the qualifiers.
    bool IsLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
    Qualifiers Quals = QT.getQualifiers();
    QT = getFullyQualifiedType(QT->getPointeeType(), Ctx);
    // Add the r- or l-value reference type back to the fully
    // qualified one.
    if (IsLValueRefTy)
      QT = Ctx.getLValueReferenceType(QT);
    else
      QT = Ctx.getRValueReferenceType(QT);
    // Add back the qualifiers.
    QT = Ctx.getQualifiedType(QT, Quals);
    return QT;
  }

  // Remove the part of the type related to the type being a template
  // parameter (we won't report it as part of the 'type name' and it
  // is actually make the code below to be more complex (to handle
  // those)
  while (isa<SubstTemplateTypeParmType>(QT.getTypePtr())) {
    // Get the qualifiers.
    Qualifiers Quals = QT.getQualifiers();

    QT = dyn_cast<SubstTemplateTypeParmType>(QT.getTypePtr())->desugar();

    // Add back the qualifiers.
    QT = Ctx.getQualifiedType(QT, Quals);
  }

  NestedNameSpecifier *Prefix = nullptr;
  Qualifiers PrefixQualifiers;
  ElaboratedTypeKeyword Keyword = ETK_None;
  if (const auto *ETypeInput = dyn_cast<ElaboratedType>(QT.getTypePtr())) {
    QT = ETypeInput->getNamedType();
    Keyword = ETypeInput->getKeyword();
  }
  // Create a nested name specifier if needed (i.e. if the decl context
  // is not the global scope.
  Prefix = createNestedNameSpecifierForScopeOf(Ctx, QT.getTypePtr(),
                                               true /*FullyQualified*/);

  // move the qualifiers on the outer type (avoid 'std::const string'!)
  if (Prefix) {
    PrefixQualifiers = QT.getLocalQualifiers();
    QT = QualType(QT.getTypePtr(), 0);
  }

  // In case of template specializations iterate over the arguments and
  // fully qualify them as well.
  if (isa<const TemplateSpecializationType>(QT.getTypePtr()) ||
      isa<const RecordType>(QT.getTypePtr())) {
    // We are asked to fully qualify and we have a Record Type (which
    // may pont to a template specialization) or Template
    // Specialization Type. We need to fully qualify their arguments.

    Qualifiers Quals = QT.getLocalQualifiers();
    const Type *TypePtr = getFullyQualifiedTemplateType(Ctx, QT.getTypePtr());
    QT = Ctx.getQualifiedType(TypePtr, Quals);
  }
  if (Prefix || Keyword != ETK_None) {
    QT = Ctx.getElaboratedType(Keyword, Prefix, QT);
    QT = Ctx.getQualifiedType(QT, PrefixQualifiers);
  }
  return QT;
}
Exemplo n.º 9
0
/// \brief Convert the specified DeclSpec to the appropriate type object.
QualType Sema::ActOnTypeName(ASTContext &C, DeclSpec &DS) {
  QualType Result;
  switch (DS.getTypeSpecType()) {
  case DeclSpec::TST_integer:
    Result = C.IntegerTy;
    break;
  case DeclSpec::TST_unspecified: // FIXME: Correct?
  case DeclSpec::TST_real:
    Result = C.RealTy;
    break;
  case DeclSpec::TST_character:
    if(DS.isStarLengthSelector())
      Result = C.NoLengthCharacterTy;
    else if(DS.hasLengthSelector())
      Result = QualType(C.getCharacterType(
                          EvalAndCheckCharacterLength(DS.getLengthSelector())), 0);
    else Result = C.CharacterTy;
    break;
  case DeclSpec::TST_logical:
    Result = C.LogicalTy;
    break;
  case DeclSpec::TST_complex:
    Result = C.ComplexTy;
    break;
  case DeclSpec::TST_struct:
    if(!DS.getRecord())
      Result = C.RealTy;
    else
      Result = C.getRecordType(DS.getRecord());
    break;
  }

  Type::TypeKind Kind = Type::NoKind;
  if(DS.hasKindSelector())
    Kind = EvalAndCheckTypeKind(Result, DS.getKindSelector());

  if(Kind != Type::NoKind || DS.isDoublePrecision() || DS.isByte()) {
    switch (DS.getTypeSpecType()) {
    case DeclSpec::TST_integer:
      Result = Kind == Type::NoKind? C.IntegerTy :
                         QualType(C.getBuiltinType(BuiltinType::Integer, Kind, true), 0);
      break;
    case DeclSpec::TST_real:
      Result = Kind == Type::NoKind? (DS.isDoublePrecision()? C.DoublePrecisionTy : C.RealTy) :
                         QualType(C.getBuiltinType(BuiltinType::Real, Kind, true), 0);
      break;
    case DeclSpec::TST_logical:
      Result = Kind == Type::NoKind? (DS.isByte()? C.ByteTy : C.LogicalTy) :
                         QualType(C.getBuiltinType(BuiltinType::Logical, Kind, true), 0);
      break;
    case DeclSpec::TST_complex:
      Result = Kind == Type::NoKind? (DS.isDoublePrecision()? C.DoubleComplexTy : C.ComplexTy) :
                         QualType(C.getBuiltinType(BuiltinType::Complex, Kind, true), 0);
      break;
    default:
      break;
    }
  }

  if (!DS.hasAttributes())
    return Result;

  const Type *TypeNode = Result.getTypePtr();
  Qualifiers Quals = Qualifiers::fromOpaqueValue(DS.getAttributeSpecs());
  Quals.setIntentAttr(DS.getIntentSpec());
  Quals.setAccessAttr(DS.getAccessSpec());

  Result = C.getExtQualType(TypeNode, Quals);

  if (!Quals.hasAttributeSpec(Qualifiers::AS_dimension))
    return Result;

  return ActOnArraySpec(C, Result, DS.getDimensions());
}