35 #include <clang/AST/ASTContext.h>
36 #include <clang/AST/Expr.h>
37 #include <clang/AST/ExprCXX.h>
38 #include <clang/AST/ExprObjC.h>
39 #include <clang/Basic/Diagnostic.h>
40 #include <clang/Lex/Lexer.h>
42 #include <llvm/ADT/StringSwitch.h>
47 using namespace clang;
48 using namespace tesla;
51 Parser* Parser::AssertionParser(CallExpr *Call, ASTContext& Ctx) {
54 OwningPtr<Parser> Bootstrap(
new Parser(Ctx));
56 if (Call->getNumArgs() != 7) {
57 Bootstrap->ReportError(
58 "expected seven arguments: "
59 "filename, line, counter, context, start, end, expression",
64 Expr *Filename = Call->getArg(0);
65 Expr *Line = Call->getArg(1);
66 Expr *Counter = Call->getArg(2);
67 Expr *Context = Call->getArg(3);
68 Expr *Beginning = Call->getArg(4);
69 Expr *End = Call->getArg(5);
73 if (!Bootstrap->Parse(ID.mutable_location(), Filename, Line, Counter))
77 if (!Bootstrap->Parse(&TeslaContext, Context))
81 RootFlags.FnInstrContext = FunctionEvent::Callee;
82 RootFlags.OrOperator = BooleanExpr::BE_Or;
83 RootFlags.StrictMode =
false;
85 return new Parser(Ctx, ID, TeslaContext, Beginning, End, Expression, RootFlags);
89 Parser* Parser::AutomatonParser(FunctionDecl *F, ASTContext& Ctx) {
91 assert(F->doesThisDeclarationHaveABody());
94 ID.set_name(F->getName());
96 OwningPtr<Parser> Bootstrap(
new Parser(Ctx));
99 if (F->getNumParams() != 1) {
100 Bootstrap->ReportError(
"expected one parameter: the struct", F);
107 ValueDecl *StructRef = F->getParamDecl(0);
109 const PointerType *StructPtrTy = dyn_cast<PointerType>(StructRef->getType());
110 if (!StructPtrTy || !StructPtrTy->getPointeeType()->getAsStructureType()) {
111 Bootstrap->ReportError(
"expected pointer to struct", StructRef);
116 RootFlags.FnInstrContext = FunctionEvent::Callee;
117 RootFlags.OrOperator = BooleanExpr::BE_Xor;
118 RootFlags.StrictMode =
true;
120 return new Parser(Ctx, ID, Context, NULL, NULL, F->getBody(), RootFlags);
124 Parser* Parser::MappingParser(FunctionDecl *F, ASTContext& Ctx) {
126 assert(F->doesThisDeclarationHaveABody());
128 OwningPtr<Parser> Bootstrap(
new Parser(Ctx));
130 auto Body = dyn_cast<CompoundStmt>(F->getBody());
132 Bootstrap->ReportError(
"expected a function body (compound statement)", F);
136 if (Body->size() != 1) {
137 Bootstrap->ReportError(
"expected a single statement", F->getBody());
141 auto Ret = dyn_cast<ReturnStmt>(Body->body_back());
143 Bootstrap->ReportError(
"expected a return statement", Body->body_back());
147 auto Call = dyn_cast<CallExpr>(Ret->getRetValue());
148 if (!Call || !Call->getDirectCallee()
150 Bootstrap->ReportError(
"expected call to " +
AUTOMATON_USES, Ret);
155 const size_t ArgCount =
sizeof(Args) /
sizeof(Args[0]);
157 if (Call->getNumArgs() != ArgCount) {
158 Bootstrap->ReportError(
"expected automaton, locality, start, end", Call);
162 for (
size_t i = 0; i < ArgCount; i++)
163 Args[i] = Call->getArg(i)->IgnoreImplicit();
165 auto Automaton = Bootstrap->ParseStringLiteral(Call->getArg(0));
167 Bootstrap->ReportError(
"expected automaton name", Call->getArg(0));
171 auto Locality = dyn_cast<DeclRefExpr>(Call->getArg(1)->IgnoreImplicit());
173 Bootstrap->ReportError(
"expected TESLA locality", Call->getArg(1));
177 auto Beginning = Call->getArg(2);
178 auto End = Call->getArg(3);
184 if (!Bootstrap->Parse(&Context, Locality))
188 RootFlags.FnInstrContext = FunctionEvent::Callee;
190 return new Parser(Ctx, ID, Context, Beginning, End, NULL, RootFlags);
194 bool Parser::Parse(
Expression *E,
const CompoundStmt *C, Flags F) {
200 Sequence *Seq = E->mutable_sequence();
202 for (
auto i = C->body_begin(); i != C->body_end(); i++) {
205 if (
auto *R = dyn_cast<ReturnStmt>(S)) {
207 const Expr *RetVal = R->getRetValue();
208 if (RetVal == NULL) {
209 ReportError(
"automaton description returns nothing", R);
213 auto *DoneCall = dyn_cast<CallExpr>(RetVal->IgnoreParenCasts());
214 if (DoneCall == NULL) {
215 ReportError(
"expected __tesla_automaton_done", RetVal);
219 }
else if (
auto *E = dyn_cast<Expr>(S)) {
221 if (!Parse(Seq->add_expression(), E, F))
234 bool Parser::Parse(
Location *Loc, Expr *Filename, Expr *Line, Expr *Count) {
235 *Loc->mutable_filename() = ParseStringLiteral(Filename);
237 auto LineNumber = ParseIntegerLiteral(Line);
238 if (LineNumber.getBitWidth() == 0) {
242 Loc->set_line(LineNumber.getLimitedValue());
244 auto Counter = ParseIntegerLiteral(Count);
245 if (Counter.getBitWidth() == 0) {
249 Loc->set_counter(Counter.getLimitedValue());
256 auto DRE = dyn_cast<DeclRefExpr>(E->IgnoreImplicit());
258 ReportError(
"invalid locality specifier (must be per-thread or global)", E);
262 StringRef Name = DRE->getDecl()->getName();
264 if (Name ==
GLOBAL) *Context = AutomatonDescription::Global;
265 else if (Name ==
PERTHREAD) *Context = AutomatonDescription::ThreadLocal;
267 ReportError(
"invalid locality specifier (must be per-thread or global)", E);
275 bool Parser::Parse(OwningPtr<AutomatonDescription>& Description,
276 OwningPtr<Usage>& Use) {
278 *A->mutable_identifier() = ID;
281 OwningPtr<Usage> U(
new Usage);
282 *U->mutable_identifier() = ID;
285 if (Beginning && !Parse(U->mutable_beginning(), Beginning, RootFlags))
288 if (End && !Parse(U->mutable_end(), End, RootFlags))
293 bool Success =
false;
294 if (
auto *C = dyn_cast<CompoundStmt>(Root))
295 Success = Parse(A->mutable_expression(), C, RootFlags);
297 else if (
auto *E = dyn_cast<Expr>(Root))
298 Success = Parse(A->mutable_expression(), E, RootFlags);
301 ReportError(
"expected expression or compound statement", Root);
308 for (
const ValueDecl *D : References)
309 if (!Parse(A->add_argument(), D,
false, RootFlags))
312 if (A->has_expression())
315 if (U->has_beginning() || U->has_end())
322 bool Parser::Parse(
Expression *Ex,
const Expr *E, Flags F) {
326 E = E->IgnoreImplicit();
328 if (
auto Assign = dyn_cast<CompoundAssignOperator>(E))
329 return ParseFieldAssign(Ex, Assign, F);
331 if (
auto Bop = dyn_cast<BinaryOperator>(E))
332 return Parse(Ex, Bop, F);
334 if (
auto Call = dyn_cast<CallExpr>(E))
335 return Parse(Ex, Call, F);
337 if (
auto DRE = dyn_cast<DeclRefExpr>(E))
338 return Parse(Ex, DRE, F);
340 if (
auto U = dyn_cast<UnaryOperator>(E))
341 return Parse(Ex, U, F);
348 bool Parser::Parse(
Expression *E,
const BinaryOperator *Bop, Flags F) {
350 assert(BooleanExpr_Operation_IsValid(F.OrOperator));
354 switch (Bop->getOpcode()) {
359 case BO_Assign:
return ParseFieldAssign(E, Bop, F);
360 case BO_EQ:
return ParseFunctionCall(E, Bop, F);
362 case BO_LAnd: Op = BooleanExpr::BE_And;
break;
363 case BO_LOr: Op = F.OrOperator;
break;
366 E->set_type(Expression::BOOLEAN_EXPR);
368 auto *BE = E->mutable_booleanexpr();
369 BE->set_operation(Op);
371 return Parse(BE->add_expression(), Bop->getLHS(), F)
372 && Parse(BE->add_expression(), Bop->getRHS(), F);
376 bool Parser::Parse(
Expression *E,
const CallExpr *Call, Flags F) {
378 const FunctionDecl *Fun = Call->getDirectCallee();
380 ReportError(
"expected direct call to predicate or sub-automaton", Call);
384 const Type *RetTy = Fun->getResultType().getTypePtr();
385 auto *PtrTy = dyn_cast<PointerType>(RetTy);
387 ReportError(
"expected predicate or sub-automaton", Call);
391 auto *StructTy = PtrTy->getPointeeType()->getAsStructureType();
393 ReportError(
"expected pointer-to-struct return type", Call);
397 RecordDecl *Struct = StructTy->getDecl();
399 auto Parse = llvm::StringSwitch<CallParser>(Struct->getName())
400 .Case(
"__tesla_automaton_description", &Parser::ParseSubAutomaton)
401 .Case(
"__tesla_event", &Parser::ParsePredicate)
409 return (this->*Parse)(E, Call, F);
413 bool Parser::Parse(
Expression *E,
const DeclRefExpr *Ref, Flags F) {
414 auto D = Ref->getDecl();
417 if (D->getName() ==
NOW) {
419 *E->mutable_now()->mutable_location() = ID.location();
423 else if (D->getName() ==
IGNORE) {
425 E->set_type(Expression::NULL_EXPR);
434 bool Parser::Parse(
Expression *E,
const UnaryOperator *U, Flags F) {
436 E->set_type(Expression::FIELD_ASSIGN);
438 A->set_strict(F.StrictMode);
442 switch(U->getOpcode()) {
445 A->set_operation(FieldAssignment::PlusEqual);
450 A->set_operation(FieldAssignment::MinusEqual);
458 auto *RHS = A->mutable_value();
459 RHS->set_type(Argument::Constant);
462 auto ME = dyn_cast<MemberExpr>(U->getSubExpr());
464 ReportError(
"expected struct member", U->getSubExpr());
468 return CheckAssignmentKind(ME->getMemberDecl(), U)
469 && ParseStructField(A->mutable_field(), ME, F);
473 bool Parser::ParseSequence(
Expression *E,
const CallExpr *Call, Flags F) {
476 Sequence *Seq = E->mutable_sequence();
478 for (
auto Arg = Call->arg_begin(); Arg != Call->arg_end(); ++Arg)
479 if (!Parse(Seq->add_expression(), *Arg, F))
486 bool Parser::ParseSubAutomaton(
Expression *E,
const CallExpr *Call, Flags F) {
487 E->set_type(Expression::SUB_AUTOMATON);
488 E->mutable_subautomaton()->set_name(Call->getDirectCallee()->getName());
493 bool Parser::ParsePredicate(
Expression *E,
const CallExpr *Call, Flags F) {
494 const FunctionDecl *Fun = Call->getDirectCallee();
497 auto Parse = llvm::StringSwitch<CallParser>(Fun->getName())
498 .Case(
"__tesla_call", &Parser::ParseFunctionCall)
499 .Case(
"__tesla_return", &Parser::ParseFunctionReturn)
500 .Case(
"__tesla_callee", &Parser::ParseCallee)
501 .Case(
"__tesla_caller", &Parser::ParseCaller)
502 .Case(
"__tesla_strict", &Parser::ParseStrictMode)
503 .Case(
"__tesla_conditional", &Parser::ParseConditional)
504 .Case(
"__tesla_sequence", &Parser::ParseSequence)
505 .Case(
"__tesla_optional", &Parser::ParseOptional)
513 return (this->*Parse)(E, Call, F);
517 bool Parser::ParseOptional(
Expression *E,
const CallExpr *Call, Flags F) {
522 if (Call->getNumArgs() != 2) {
523 ReportError(
"'optional' predicate takes exactly one user argument", Call);
528 E->set_type(Expression::BOOLEAN_EXPR);
530 B->set_operation(BooleanExpr::BE_Xor);
532 B->add_expression()->set_type(Expression::NULL_EXPR);
533 return Parse(B->add_expression(), Call->getArg(1), F);
537 bool Parser::ParseFunctionCall(
Expression *E,
const BinaryOperator *Bop,
540 E->set_type(Expression::FUNCTION);
543 FnEvent->set_context(F.FnInstrContext);
544 FnEvent->set_strict(F.StrictMode);
548 FnEvent->set_direction(FunctionEvent::Exit);
550 Expr *LHS = Bop->getLHS();
551 bool LHSisICE = LHS->isIntegerConstantExpr(Ctx);
553 Expr *RHS = Bop->getRHS();
555 if (!(LHSisICE ^ RHS->isIntegerConstantExpr(Ctx))) {
556 ReportError(
"one of {LHS,RHS} must be a constant", Bop);
560 Expr *RetVal = (LHSisICE ? LHS : RHS);
561 Expr *FnCall = (LHSisICE ? RHS : LHS);
562 if (!Parse(FnEvent->mutable_expectedreturnvalue(), RetVal, F))
565 auto FnCallExpr = dyn_cast<CallExpr>(FnCall);
571 auto Fn = FnCallExpr->getDirectCallee();
573 ReportError(
"not a direct function call", FnCallExpr);
577 if (!Parse(FnEvent->mutable_function(), Fn, F))
580 for (
auto I = FnCallExpr->arg_begin(); I != FnCallExpr->arg_end(); ++I) {
581 if (!Parse(FnEvent->add_argument(), I->IgnoreImplicit(), F))
589 bool Parser::ParseFunctionCall(
Expression *E,
const CallExpr *Call, Flags F) {
591 E->set_type(Expression::FUNCTION);
594 FnEvent->set_direction(FunctionEvent::Entry);
595 FnEvent->set_strict(F.StrictMode);
597 return ParseFunctionPredicate(FnEvent, Call,
false, F);
601 bool Parser::ParseFunctionReturn(
Expression *E,
const CallExpr *Call, Flags F) {
603 E->set_type(Expression::FUNCTION);
606 FnEvent->set_direction(FunctionEvent::Exit);
607 FnEvent->set_strict(F.StrictMode);
609 return ParseFunctionPredicate(FnEvent, Call,
true, F);
613 bool Parser::ParseCallee(
Expression *E,
const clang::CallExpr *Call, Flags F) {
615 F.FnInstrContext = FunctionEvent::Callee;
617 if (Call->getNumArgs() != 2) {
618 ReportError(
"expected two arguments: __tesla_ignore, expression", Call);
622 return CheckIgnore(Call->getArg(0))
623 && Parse(E, Call->getArg(1), F);
627 bool Parser::ParseCaller(
Expression *E,
const clang::CallExpr *Call, Flags F) {
629 F.FnInstrContext = FunctionEvent::Caller;
631 if (Call->getNumArgs() != 2) {
632 ReportError(
"expected two arguments: __tesla_ignore, expression", Call);
636 return CheckIgnore(Call->getArg(0))
637 && Parse(E, Call->getArg(1), F);
641 bool Parser::ParseStrictMode(
Expression *E,
const clang::CallExpr *Call,
644 if (Call->getNumArgs() != 2) {
645 ReportError(
"expected two arguments: __tesla_ignore, expression", Call);
650 return CheckIgnore(Call->getArg(0))
651 && Parse(E, Call->getArg(1), F);
655 bool Parser::ParseConditional(
Expression *E,
const clang::CallExpr *Call,
658 if (Call->getNumArgs() != 2) {
659 ReportError(
"expected two arguments: __tesla_ignore, expression", Call);
663 F.StrictMode =
false;
664 return CheckIgnore(Call->getArg(0))
665 && Parse(E, Call->getArg(1), F);
669 bool Parser::ParseFunctionPredicate(
FunctionEvent *Event,
const CallExpr *Call,
670 bool ParseRetVal, Flags F) {
672 Event->set_context(F.FnInstrContext);
676 if (Call->getNumArgs() < 1) {
681 auto Arg = Call->getArg(0)->IgnoreParenCasts();
682 auto FnRef = dyn_cast<DeclRefExpr>(Arg);
684 const FunctionDecl *Fn = 0;
686 const ObjCMethodDecl *Meth = 0;
688 const Expr *
const*Args;
689 SmallVector<const Expr*, 8> ArgsVector;
693 Args = Call->getArgs() + 1;
694 ArgCount = Call->getNumArgs() - 1;
696 if (
const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Arg))
697 if (BinOp->getOpcode() == BO_Comma) {
698 Arg = BinOp->getLHS()->IgnoreParenCasts();
701 if (isa<BinaryOperator>(Arg))
702 while (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(Arg)) {
703 ArgsVector.push_back(BO->getRHS()->IgnoreParenCasts());
704 Arg = BO->getLHS()->IgnoreParenCasts();
706 if ((FnRef = dyn_cast<DeclRefExpr>(Arg))) {
707 std::reverse(ArgsVector.begin(), ArgsVector.end());
708 ArgCount = ArgsVector.size();
709 Args = ArgsVector.data();
710 }
else if (
const CallExpr *CE = dyn_cast<CallExpr>(Arg)) {
714 Fn = CE->getDirectCallee();
717 Args = CE->getArgs();
718 ArgCount = CE->getNumArgs();
719 }
else if (
const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(Arg)) {
720 Meth = OME->getMethodDecl();
722 ReportError(
"types of Objective-C method to be instrumented must be known", OME);
726 switch (OME->getReceiverKind()) {
727 default: assert(0);
break;
728 case ObjCMessageExpr::Class:
729 Event->mutable_receiver()->set_name(OME->getReceiverInterface()->getName());
730 kind = FunctionEvent::ObjCClassMessage;
732 case ObjCMessageExpr::Instance:
733 Parse(Event->mutable_receiver(), OME->getInstanceReceiver(), F);
734 kind = FunctionEvent::ObjCInstanceMessage;
736 case ObjCMessageExpr::SuperClass:
737 case ObjCMessageExpr::SuperInstance:
738 kind = FunctionEvent::ObjCSuperMessage;
741 Event->set_kind(kind);
742 Event->mutable_function()->set_name(Meth->getNameAsString());
743 Args = OME->getArgs();
744 ArgCount = OME->getNumArgs();
754 Fn = dyn_cast<FunctionDecl>(FnRef->getDecl());
757 ReportError(
"called() must refer to a function or method call", Call);
761 bool HaveRetVal = ParseRetVal &&
762 (Fn ? !Fn->getResultType()->isVoidType()
763 : Meth->getResultType()->isVoidType()) ;
769 const size_t ExpectedSize = (Fn ? Fn->param_size() : Meth->param_size())
770 + (HaveRetVal ? 1 : 0);
773 if (ArgCount != ExpectedSize) {
774 ReportError(
"specify all args (possibly __tesla_any()) or none", Call);
778 for (
size_t i = 0; i < ArgCount; i++) {
779 if (!Parse(Event->add_argument(), Args[i], F))
785 if (!Parse(Event->mutable_expectedreturnvalue(),
786 Args[ArgCount-1], F))
794 for (
auto I = Fn->param_begin(); I != Fn->param_end(); ++I) {
795 if (!Parse(Event->add_argument(), *I,
true, F))
799 for (
auto I = Meth->param_begin(); I != Meth->param_end(); ++I) {
800 if (!Parse(Event->add_argument(), *I,
true, F))
806 Event->mutable_expectedreturnvalue()->set_type(Argument::Any);
809 return Fn ? Parse(Event->mutable_function(), Fn, F) :
true;
813 bool Parser::ParseFieldAssign(
Expression *E,
const clang::BinaryOperator *O,
816 E->set_type(Expression::FIELD_ASSIGN);
818 A->set_strict(F.StrictMode);
820 switch (O->getOpcode()) {
822 ReportError(
"unhandled compound assignment type", O);
825 case BO_Assign: A->set_operation(FieldAssignment::SimpleAssign);
break;
826 case BO_AddAssign: A->set_operation(FieldAssignment::PlusEqual);
break;
827 case BO_SubAssign: A->set_operation(FieldAssignment::MinusEqual);
break;
830 auto *LHS = dyn_cast<MemberExpr>(O->getLHS());
836 return CheckAssignmentKind(LHS->getMemberDecl(), O)
837 && ParseStructField(A->mutable_field(), LHS, F)
838 && Parse(A->mutable_value(), O->getRHS(), F);
842 bool Parser::ParseStructField(
StructField *Field,
const MemberExpr *ME,
845 dyn_cast<DeclRefExpr>(ME->getBase()->IgnoreImpCasts())->getDecl();
847 auto BaseType = Base->getType();
849 if (
auto *BasePtrType = dyn_cast<PointerType>(BaseType))
850 BaseType = BasePtrType->getPointeeType();
852 if (BaseType.isNull()) {
853 ReportError(
"base of assignment ME not a struct type", Base);
857 Field->set_type(BaseType->getAsStructureType()->getDecl()->getName());
859 auto *Member = dyn_cast<FieldDecl>(ME->getMemberDecl());
861 ReportError(
"struct member is not a FieldDecl", ME);
865 Field->set_index(Member->getFieldIndex());
866 Field->set_name(Member->getName());
868 return Parse(Field->mutable_base(), Base,
false, F);
872 bool Parser::Parse(
Argument *Arg,
const Expr *E, Flags F) {
876 auto P = E->IgnoreParenCasts();
877 llvm::APSInt ConstValue;
886 if (
auto Call = dyn_cast<CallExpr>(P)) {
887 auto Fn = Call->getDirectCallee();
893 StringRef Name = Fn->getName();
896 if (Call->getNumArgs() != 1) {
901 Arg->set_constantmatch(
902 (Name ==
FLAGS) ? Argument::Flags : Argument::Mask);
905 }
else if (Name.slice(0,
ANY.length()) ==
ANY) {
906 Arg->set_type(Argument::Any);
910 ReportError(
"expected __tesla_{flags,mask,any}", P);
916 if (
auto DRE = dyn_cast<DeclRefExpr>(P)) {
917 Arg->set_type(Argument::Variable);
918 const ValueDecl *D = DRE->getDecl();
920 *Arg->mutable_name() = DRE->getDecl()->getName();
921 Arg->set_index(ReferenceIndex(D));
925 if (P->isIntegerConstantExpr(ConstValue, Ctx)) {
926 Arg->set_type(Argument::Constant);
927 Arg->set_value(ConstValue.getSExtValue());
930 SourceLocation Loc = P->getLocStart();
931 if (Loc.isMacroID()) {
948 auto& SM = Ctx.getSourceManager();
950 const char *RawCharData = SM.getCharacterData(Loc);
951 const char *SpellingCharData = SM.getCharacterData(
952 SM.getSLocEntry(SM.getFileID(Loc))
956 if (RawCharData == SpellingCharData)
957 *Arg->mutable_name() =
958 Lexer::getImmediateMacroName(Loc, SM, Ctx.getLangOpts());
966 if (
auto *UO = dyn_cast<UnaryOperator>(P)) {
967 if (UO->getOpcode() == UO_AddrOf) {
968 Arg->set_type(Argument::Indirect);
969 return Parse(Arg->mutable_indirection(), UO->getSubExpr(), F);
974 if (
auto *ME = dyn_cast<MemberExpr>(P)) {
975 Arg->set_type(Argument::Field);
976 return ParseStructField(Arg->mutable_field(), ME, F);
980 ReportError(
"Invalid argument to function within TESLA assertion", P);
984 bool Parser::Parse(
FunctionRef *FnRef,
const FunctionDecl *Fn, Flags F) {
985 FnRef->set_name(Fn->getName());
986 if (FnRef->
name().empty()) {
995 bool Parser::Parse(
Argument *Arg,
const ValueDecl *D,
bool AllowAny, Flags F) {
999 *Arg->mutable_name() = D->getName();
1002 Arg->set_type(Argument::Any);
1004 Arg->set_type(Argument::Variable);
1005 Arg->set_index(ReferenceIndex(D));
1012 bool Parser::CheckIgnore(
const Expr *E) {
1013 auto *IgnoreRef = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts());
1014 if (!IgnoreRef || IgnoreRef->getDecl()->getName() !=
IGNORE) {
1024 static inline bool SimpleAssignment(
const Expr *E) {
1025 auto *BO = dyn_cast<BinaryOperator>(E);
1026 return (BO != NULL) && (BO->getOpcode() == BO_Assign);
1029 bool Parser::CheckAssignmentKind(
const ValueDecl *Field,
const Expr *E) {
1030 auto i = FieldAssignments.find(Field);
1031 if (i == FieldAssignments.end()) {
1032 FieldAssignments[Field] = E;
1036 auto *Old = i->second;
1038 if (SimpleAssignment(E) == SimpleAssignment(Old))
1041 static DiagnosticsEngine& Diag = Ctx.getDiagnostics();
1042 static int Warn = Diag.getCustomDiagID(DiagnosticsEngine::Warning,
1043 "TESLA: mixing instrumentation of simple and compound assignments");
1045 static int Note = Diag.getCustomDiagID(DiagnosticsEngine::Note,
1046 "TESLA: previous assignment here");
1048 Diag.Report(E->getLocStart(), Warn) << E->getSourceRange();
1049 Diag.Report(Old->getLocStart(), Note) << Old->getSourceRange();
1055 size_t Parser::ReferenceIndex(
const ValueDecl* D) {
1058 for (
auto I = References.begin(); I != References.end(); I++)
1064 References.push_back(D);
1071 ReportError(Message, D->getLocStart(), D->getSourceRange());
1076 ReportError(Message, S->getLocStart(), S->getSourceRange());
1081 const SourceRange& Range) {
1083 static const DiagnosticsEngine::Level Level = DiagnosticsEngine::Error;
1085 DiagnosticsEngine& Diag = Ctx.getDiagnostics();
1086 int DiagID = Diag.getCustomDiagID(Level, (
"TESLA: " + Message).str());
1088 Diag.Report(Start, DiagID) << Range;
1092 std::string Parser::ParseStringLiteral(
const Expr* E) {
1093 auto LiteralValue = dyn_cast<StringLiteral>(E->IgnoreImplicit());
1094 if (!LiteralValue) {
1099 return LiteralValue->getString();
1103 llvm::APInt Parser::ParseIntegerLiteral(
const Expr* E) {
1104 auto LiteralValue = dyn_cast<IntegerLiteral>(E->IgnoreImplicit());
1105 if (!LiteralValue) {
1107 return llvm::APInt();
1110 return LiteralValue->getValue();