Decl *Sema::ActOnIntrinsicEntityDecl(ASTContext &C, QualType T, SourceLocation IDLoc, const IdentifierInfo *IDInfo) { auto FuncResult = IntrinsicFunctionMapping.Resolve(IDInfo); if(FuncResult.IsInvalid) { Diags.Report(IDLoc, diag::err_intrinsic_invalid_func) << IDInfo << getTokenRange(IDLoc); return nullptr; } QualType Type = T.isNull()? C.RealTy : T; if (auto Prev = LookupIdentifier(IDInfo)) { auto Quals = getDeclQualifiers(Prev); if(Quals.hasAttributeSpec(Qualifiers::AS_intrinsic)) { Diags.Report(IDLoc, diag::err_duplicate_attr_spec) << DeclSpec::getSpecifierName(Qualifiers::AS_intrinsic); return Prev; } auto VD = dyn_cast<VarDecl>(Prev); if(VD && VD->isUnusedSymbol()) { Type = VD->getType(); CurContext->removeDecl(VD); } else { DiagnoseRedefinition(IDLoc, IDInfo, Prev); return nullptr; } } auto Decl = IntrinsicFunctionDecl::Create(C, CurContext, IDLoc, IDInfo, Type, FuncResult.Function); CurContext->addDecl(Decl); return Decl; }
bool DataStmtEngine::CheckVar(VarExpr *E) { auto VD = E->getVarDecl(); if(VD->isArgument() || VD->isParameter() || VD->isFunctionResult()) { Diags.Report(E->getLocation(), diag::err_data_stmt_invalid_var) << (VD->isParameter()? 0 : VD->isArgument()? 1 : 2) << VD->getIdentifier() << E->getSourceRange(); getValueOnError(); return true; } if(VD->isUnusedSymbol()) const_cast<VarDecl*>(VD)->MarkUsedAsVariable(E->getLocation()); return false; }
bool Sema::CheckEquivalenceObject(SourceLocation Loc, Expr *E, VarDecl *& Object) { if(auto Var = dyn_cast<VarExpr>(E)) { auto VD = Var->getVarDecl(); if(VD->isArgument() || VD->isParameter()) { Diags.Report(Loc, diag::err_spec_requires_local_var) << E->getSourceRange(); Diags.Report(VD->getLocation(), diag::note_previous_definition_kind) << VD->getIdentifier() << (VD->isArgument()? 0 : 1) << getTokenRange(VD->getLocation()); return true; } if(VD->isUnusedSymbol()) const_cast<VarDecl*>(VD)->MarkUsedAsVariable(E->getLocation()); Object = const_cast<VarDecl*>(VD); } else { Diags.Report(Loc, diag::err_spec_requires_var_or_arr_el) << E->getSourceRange(); return true; } return false; }
Decl *Sema::ActOnExternalEntityDecl(ASTContext &C, QualType T, SourceLocation IDLoc, const IdentifierInfo *IDInfo) { SourceLocation TypeLoc; VarDecl *ArgumentExternal = nullptr; if (auto Prev = LookupIdentifier(IDInfo)) { auto Quals = getDeclQualifiers(Prev); if(Quals.hasAttributeSpec(Qualifiers::AS_external)) { Diags.Report(IDLoc, diag::err_duplicate_attr_spec) << DeclSpec::getSpecifierName(Qualifiers::AS_external); return Prev; } // apply EXTERNAL to an unused symbol or an argument. auto VD = dyn_cast<VarDecl>(Prev); if(VD && (VD->isUnusedSymbol() || VD->isArgument()) ) { T = VD->getType(); TypeLoc = VD->getLocation(); CurContext->removeDecl(VD); if(VD->isArgument()) ArgumentExternal = VD; } else { DiagnoseRedefinition(IDLoc, IDInfo, Prev); return nullptr; } } if(T.isNull()) T = C.VoidTy; DeclarationNameInfo DeclName(IDInfo,IDLoc); auto Decl = FunctionDecl::Create(C, ArgumentExternal? FunctionDecl::ExternalArgument : FunctionDecl::External, CurContext, DeclName, T); SetFunctionType(Decl, T, TypeLoc, SourceRange()); //FIXME: proper loc, and range CurContext->addDecl(Decl); if(ArgumentExternal) ArgumentExternal->setType(C.getFunctionType(Decl)); return Decl; }