Computer Laboratory

Parser.cpp
Go to the documentation of this file.
1 
2 /*
3  * Copyright (c) 2012-2013 Jonathan Anderson
4  * All rights reserved.
5  *
6  * This software was developed by SRI International and the University of
7  * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
8  * ("CTSRD"), as part of the DARPA CRASH research programme.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in the
17  * documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include "Names.h"
33 #include "Parser.h"
34 
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>
41 
42 #include <llvm/ADT/StringSwitch.h>
43 #include <algorithm>
44 
45 #include <tesla.pb.h>
46 
47 using namespace clang;
48 using namespace tesla;
49 
50 
51 Parser* Parser::AssertionParser(CallExpr *Call, ASTContext& Ctx) {
52  assert(Call->getDirectCallee()->getName().compare(INLINE_ASSERTION) == 0);
53 
54  OwningPtr<Parser> Bootstrap(new Parser(Ctx));
55 
56  if (Call->getNumArgs() != 7) {
57  Bootstrap->ReportError(
58  "expected seven arguments: "
59  "filename, line, counter, context, start, end, expression",
60  Call);
61  return NULL;
62  }
63 
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);
70  Expr *Expression = Call->getArg(6);
71 
72  Identifier ID;
73  if (!Bootstrap->Parse(ID.mutable_location(), Filename, Line, Counter))
74  return NULL;
75 
77  if (!Bootstrap->Parse(&TeslaContext, Context))
78  return NULL;
79 
80  Flags RootFlags;
81  RootFlags.FnInstrContext = FunctionEvent::Callee;
82  RootFlags.OrOperator = BooleanExpr::BE_Or;
83  RootFlags.StrictMode = false;
84 
85  return new Parser(Ctx, ID, TeslaContext, Beginning, End, Expression, RootFlags);
86 }
87 
88 
89 Parser* Parser::AutomatonParser(FunctionDecl *F, ASTContext& Ctx) {
90  assert(F != NULL);
91  assert(F->doesThisDeclarationHaveABody());
92 
93  Identifier ID;
94  ID.set_name(F->getName());
95 
96  OwningPtr<Parser> Bootstrap(new Parser(Ctx));
97 
98  // We should reference one variable: the struct pointer.
99  if (F->getNumParams() != 1) {
100  Bootstrap->ReportError("expected one parameter: the struct", F);
101  return NULL;
102  }
103 
104  // TODO: programmer-specified context
105  AutomatonDescription::Context Context = AutomatonDescription::Global;
106 
107  ValueDecl *StructRef = F->getParamDecl(0);
108 
109  const PointerType *StructPtrTy = dyn_cast<PointerType>(StructRef->getType());
110  if (!StructPtrTy || !StructPtrTy->getPointeeType()->getAsStructureType()) {
111  Bootstrap->ReportError("expected pointer to struct", StructRef);
112  return NULL;
113  }
114 
115  Flags RootFlags;
116  RootFlags.FnInstrContext = FunctionEvent::Callee;
117  RootFlags.OrOperator = BooleanExpr::BE_Xor;
118  RootFlags.StrictMode = true;
119 
120  return new Parser(Ctx, ID, Context, NULL, NULL, F->getBody(), RootFlags);
121 }
122 
123 
124 Parser* Parser::MappingParser(FunctionDecl *F, ASTContext& Ctx) {
125  assert(F != NULL);
126  assert(F->doesThisDeclarationHaveABody());
127 
128  OwningPtr<Parser> Bootstrap(new Parser(Ctx));
129 
130  auto Body = dyn_cast<CompoundStmt>(F->getBody());
131  if (!Body) {
132  Bootstrap->ReportError("expected a function body (compound statement)", F);
133  return NULL;
134  }
135 
136  if (Body->size() != 1) {
137  Bootstrap->ReportError("expected a single statement", F->getBody());
138  return NULL;
139  }
140 
141  auto Ret = dyn_cast<ReturnStmt>(Body->body_back());
142  if (!Ret) {
143  Bootstrap->ReportError("expected a return statement", Body->body_back());
144  return NULL;
145  }
146 
147  auto Call = dyn_cast<CallExpr>(Ret->getRetValue());
148  if (!Call || !Call->getDirectCallee()
149  || (Call->getDirectCallee()->getName() != AUTOMATON_USES)) {
150  Bootstrap->ReportError("expected call to " + AUTOMATON_USES, Ret);
151  return NULL;
152  }
153 
154  Expr* Args[4];
155  const size_t ArgCount = sizeof(Args) / sizeof(Args[0]);
156 
157  if (Call->getNumArgs() != ArgCount) {
158  Bootstrap->ReportError("expected automaton, locality, start, end", Call);
159  return NULL;
160  }
161 
162  for (size_t i = 0; i < ArgCount; i++)
163  Args[i] = Call->getArg(i)->IgnoreImplicit();
164 
165  auto Automaton = Bootstrap->ParseStringLiteral(Call->getArg(0));
166  if (Automaton.empty()) {
167  Bootstrap->ReportError("expected automaton name", Call->getArg(0));
168  return NULL;
169  }
170 
171  auto Locality = dyn_cast<DeclRefExpr>(Call->getArg(1)->IgnoreImplicit());
172  if (!Locality) {
173  Bootstrap->ReportError("expected TESLA locality", Call->getArg(1));
174  return NULL;
175  }
176 
177  auto Beginning = Call->getArg(2);
178  auto End = Call->getArg(3);
179 
180  Identifier ID;
181  ID.set_name(Automaton);
182 
184  if (!Bootstrap->Parse(&Context, Locality))
185  return NULL;
186 
187  Flags RootFlags;
188  RootFlags.FnInstrContext = FunctionEvent::Callee;
189 
190  return new Parser(Ctx, ID, Context, Beginning, End, NULL, RootFlags);
191 }
192 
193 
194 bool Parser::Parse(Expression *E, const CompoundStmt *C, Flags F) {
195  assert(E != NULL);
196  assert(C != NULL);
197 
198  // A list of statements should be treated like a sequence.
199  E->set_type(Expression::SEQUENCE);
200  Sequence *Seq = E->mutable_sequence();
201 
202  for (auto i = C->body_begin(); i != C->body_end(); i++) {
203  const Stmt *S = *i;
204 
205  if (auto *R = dyn_cast<ReturnStmt>(S)) {
206  // This must be a 'done' statement.
207  const Expr *RetVal = R->getRetValue();
208  if (RetVal == NULL) {
209  ReportError("automaton description returns nothing", R);
210  return false;
211  }
212 
213  auto *DoneCall = dyn_cast<CallExpr>(RetVal->IgnoreParenCasts());
214  if (DoneCall == NULL) {
215  ReportError("expected __tesla_automaton_done", RetVal);
216  return false;
217  }
218 
219  } else if (auto *E = dyn_cast<Expr>(S)) {
220  // Otherwise, it's just a regular TESLA expression.
221  if (!Parse(Seq->add_expression(), E, F))
222  return false;
223 
224  } else {
225  ReportError("unhandled C statement type", S);
226  return false;
227  }
228  }
229 
230  return true;
231 }
232 
233 
234 bool Parser::Parse(Location *Loc, Expr *Filename, Expr *Line, Expr *Count) {
235  *Loc->mutable_filename() = ParseStringLiteral(Filename);
236 
237  auto LineNumber = ParseIntegerLiteral(Line);
238  if (LineNumber.getBitWidth() == 0) {
239  ReportError("invalid line number", Line);
240  return false;
241  }
242  Loc->set_line(LineNumber.getLimitedValue());
243 
244  auto Counter = ParseIntegerLiteral(Count);
245  if (Counter.getBitWidth() == 0) {
246  ReportError("invalid counter value", Count);
247  return false;
248  }
249  Loc->set_counter(Counter.getLimitedValue());
250 
251  return true;
252 }
253 
254 
255 bool Parser::Parse(AutomatonDescription::Context *Context, Expr *E) {
256  auto DRE = dyn_cast<DeclRefExpr>(E->IgnoreImplicit());
257  if (!DRE) {
258  ReportError("invalid locality specifier (must be per-thread or global)", E);
259  return false;
260  }
261 
262  StringRef Name = DRE->getDecl()->getName();
263 
264  if (Name == GLOBAL) *Context = AutomatonDescription::Global;
265  else if (Name == PERTHREAD) *Context = AutomatonDescription::ThreadLocal;
266  else {
267  ReportError("invalid locality specifier (must be per-thread or global)", E);
268  return false;
269  }
270 
271  return true;
272 }
273 
274 
275 bool Parser::Parse(OwningPtr<AutomatonDescription>& Description,
276  OwningPtr<Usage>& Use) {
277  OwningPtr<AutomatonDescription> A(new AutomatonDescription);
278  *A->mutable_identifier() = ID;
279  A->set_context(TeslaContext);
280 
281  OwningPtr<Usage> U(new Usage);
282  *U->mutable_identifier() = ID;
283 
284  // Parse the automaton's [beginning,end] bounds.
285  if (Beginning && !Parse(U->mutable_beginning(), Beginning, RootFlags))
286  return false;
287 
288  if (End && !Parse(U->mutable_end(), End, RootFlags))
289  return false;
290 
291  // Parse the root: a compound statement or an expression.
292  if (Root) {
293  bool Success = false;
294  if (auto *C = dyn_cast<CompoundStmt>(Root))
295  Success = Parse(A->mutable_expression(), C, RootFlags);
296 
297  else if (auto *E = dyn_cast<Expr>(Root))
298  Success = Parse(A->mutable_expression(), E, RootFlags);
299 
300  else
301  ReportError("expected expression or compound statement", Root);
302 
303  if (!Success)
304  return false;
305  }
306 
307  // Keep track of the variables we referenced.
308  for (const ValueDecl *D : References)
309  if (!Parse(A->add_argument(), D, false, RootFlags))
310  return false;
311 
312  if (A->has_expression())
313  Description.swap(A);
314 
315  if (U->has_beginning() || U->has_end())
316  Use.swap(U);
317 
318  return true;
319 }
320 
321 
322 bool Parser::Parse(Expression *Ex, const Expr *E, Flags F) {
323  assert(Ex != NULL);
324  assert(E != NULL);
325 
326  E = E->IgnoreImplicit();
327 
328  if (auto Assign = dyn_cast<CompoundAssignOperator>(E))
329  return ParseFieldAssign(Ex, Assign, F);
330 
331  if (auto Bop = dyn_cast<BinaryOperator>(E))
332  return Parse(Ex, Bop, F);
333 
334  if (auto Call = dyn_cast<CallExpr>(E))
335  return Parse(Ex, Call, F);
336 
337  if (auto DRE = dyn_cast<DeclRefExpr>(E))
338  return Parse(Ex, DRE, F);
339 
340  if (auto U = dyn_cast<UnaryOperator>(E))
341  return Parse(Ex, U, F);
342 
343  ReportError("unsupported TESLA expression", E);
344  return false;
345 }
346 
347 
348 bool Parser::Parse(Expression *E, const BinaryOperator *Bop, Flags F) {
349 
350  assert(BooleanExpr_Operation_IsValid(F.OrOperator));
351 
353 
354  switch (Bop->getOpcode()) {
355  default:
356  ReportError("unsupported boolean operation", Bop);
357  return false;
358 
359  case BO_Assign: return ParseFieldAssign(E, Bop, F); // 'x->foo = bar'
360  case BO_EQ: return ParseFunctionCall(E, Bop, F); // 'foo(x) == y'
361 
362  case BO_LAnd: Op = BooleanExpr::BE_And; break;
363  case BO_LOr: Op = F.OrOperator; break;
364  }
365 
366  E->set_type(Expression::BOOLEAN_EXPR);
367 
368  auto *BE = E->mutable_booleanexpr();
369  BE->set_operation(Op);
370 
371  return Parse(BE->add_expression(), Bop->getLHS(), F)
372  && Parse(BE->add_expression(), Bop->getRHS(), F);
373 }
374 
375 
376 bool Parser::Parse(Expression *E, const CallExpr *Call, Flags F) {
377 
378  const FunctionDecl *Fun = Call->getDirectCallee();
379  if (!Fun) {
380  ReportError("expected direct call to predicate or sub-automaton", Call);
381  return false;
382  }
383 
384  const Type *RetTy = Fun->getResultType().getTypePtr();
385  auto *PtrTy = dyn_cast<PointerType>(RetTy);
386  if (!PtrTy) {
387  ReportError("expected predicate or sub-automaton", Call);
388  return false;
389  }
390 
391  auto *StructTy = PtrTy->getPointeeType()->getAsStructureType();
392  if (!StructTy) {
393  ReportError("expected pointer-to-struct return type", Call);
394  return false;
395  }
396 
397  RecordDecl *Struct = StructTy->getDecl();
398 
399  auto Parse = llvm::StringSwitch<CallParser>(Struct->getName())
400  .Case("__tesla_automaton_description", &Parser::ParseSubAutomaton)
401  .Case("__tesla_event", &Parser::ParsePredicate)
402  .Default(NULL);
403 
404  if (Parse == NULL) {
405  ReportError("unsupported function call", Call);
406  return false;
407  }
408 
409  return (this->*Parse)(E, Call, F);
410 }
411 
412 
413 bool Parser::Parse(Expression *E, const DeclRefExpr *Ref, Flags F) {
414  auto D = Ref->getDecl();
415  assert(D != NULL);
416 
417  if (D->getName() == NOW) {
418  E->set_type(Expression::NOW);
419  *E->mutable_now()->mutable_location() = ID.location();
420  return true;
421  }
422 
423  else if (D->getName() == IGNORE) {
424  // The __tesla_ignore "event" helps TESLA assertions look like ISO C.
425  E->set_type(Expression::NULL_EXPR);
426  return true;
427  }
428 
429  ReportError("unsupported reference", Ref);
430  return false;
431 }
432 
433 
434 bool Parser::Parse(Expression *E, const UnaryOperator *U, Flags F) {
435  // We only support unary operators in struct field expressions (for now).
436  E->set_type(Expression::FIELD_ASSIGN);
437  FieldAssignment *A = E->mutable_fieldassign();
438  A->set_strict(F.StrictMode);
439 
440  // Since we're parsing an expression, rather than an argument, we don't
441  // care about pre- vs postfix.
442  switch(U->getOpcode()) {
443  case UO_PreInc: // fall through
444  case UO_PostInc:
445  A->set_operation(FieldAssignment::PlusEqual);
446  break;
447 
448  case UO_PreDec: // fall through
449  case UO_PostDec:
450  A->set_operation(FieldAssignment::MinusEqual);
451  break;
452 
453  default:
454  ReportError("unsupported unary operator", U);
455  return false;
456  }
457 
458  auto *RHS = A->mutable_value();
459  RHS->set_type(Argument::Constant);
460  RHS->set_value(1);
461 
462  auto ME = dyn_cast<MemberExpr>(U->getSubExpr());
463  if (!ME) {
464  ReportError("expected struct member", U->getSubExpr());
465  return false;
466  }
467 
468  return CheckAssignmentKind(ME->getMemberDecl(), U)
469  && ParseStructField(A->mutable_field(), ME, F);
470 }
471 
472 
473 bool Parser::ParseSequence(Expression *E, const CallExpr *Call, Flags F) {
474 
475  E->set_type(Expression::SEQUENCE);
476  Sequence *Seq = E->mutable_sequence();
477 
478  for (auto Arg = Call->arg_begin(); Arg != Call->arg_end(); ++Arg)
479  if (!Parse(Seq->add_expression(), *Arg, F))
480  return false;
481 
482  return true;
483 }
484 
485 
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());
489  return true;
490 }
491 
492 
493 bool Parser::ParsePredicate(Expression *E, const CallExpr *Call, Flags F) {
494  const FunctionDecl *Fun = Call->getDirectCallee();
495  assert(Fun != NULL);
496 
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)
506  .Default(NULL);
507 
508  if (Parse == NULL) {
509  ReportError("unsupported predicate", Call);
510  return false;
511  }
512 
513  return (this->*Parse)(E, Call, F);
514 }
515 
516 
517 bool Parser::ParseOptional(Expression *E, const CallExpr *Call, Flags F) {
518 
519  // The 'optional' predicate actually takes two arguments ('ignore' and
520  // a programmer-supplied argument); only talk about the user argument in
521  // the error message.
522  if (Call->getNumArgs() != 2) {
523  ReportError("'optional' predicate takes exactly one user argument", Call);
524  return false;
525  }
526 
527  // Implemented as (null || optional_expression).
528  E->set_type(Expression::BOOLEAN_EXPR);
529  BooleanExpr *B = E->mutable_booleanexpr();
530  B->set_operation(BooleanExpr::BE_Xor);
531 
532  B->add_expression()->set_type(Expression::NULL_EXPR);
533  return Parse(B->add_expression(), Call->getArg(1), F);
534 }
535 
536 
537 bool Parser::ParseFunctionCall(Expression *E, const BinaryOperator *Bop,
538  Flags F) {
539 
540  E->set_type(Expression::FUNCTION);
541 
542  FunctionEvent *FnEvent = E->mutable_function();
543  FnEvent->set_context(F.FnInstrContext);
544  FnEvent->set_strict(F.StrictMode);
545 
546  // Since we might care about the return value, we must instrument exiting
547  // the function rather than entering it.
548  FnEvent->set_direction(FunctionEvent::Exit);
549 
550  Expr *LHS = Bop->getLHS();
551  bool LHSisICE = LHS->isIntegerConstantExpr(Ctx);
552 
553  Expr *RHS = Bop->getRHS();
554 
555  if (!(LHSisICE ^ RHS->isIntegerConstantExpr(Ctx))) {
556  ReportError("one of {LHS,RHS} must be a constant", Bop);
557  return false;
558  }
559 
560  Expr *RetVal = (LHSisICE ? LHS : RHS);
561  Expr *FnCall = (LHSisICE ? RHS : LHS);
562  if (!Parse(FnEvent->mutable_expectedreturnvalue(), RetVal, F))
563  return false;
564 
565  auto FnCallExpr = dyn_cast<CallExpr>(FnCall);
566  if (!FnCallExpr) {
567  ReportError("not a function call", FnCall);
568  return false;
569  }
570 
571  auto Fn = FnCallExpr->getDirectCallee();
572  if (!Fn) {
573  ReportError("not a direct function call", FnCallExpr);
574  return false;
575  }
576 
577  if (!Parse(FnEvent->mutable_function(), Fn, F))
578  return false;
579 
580  for (auto I = FnCallExpr->arg_begin(); I != FnCallExpr->arg_end(); ++I) {
581  if (!Parse(FnEvent->add_argument(), I->IgnoreImplicit(), F))
582  return false;
583  }
584 
585  return true;
586 }
587 
588 
589 bool Parser::ParseFunctionCall(Expression *E, const CallExpr *Call, Flags F) {
590 
591  E->set_type(Expression::FUNCTION);
592 
593  FunctionEvent *FnEvent = E->mutable_function();
594  FnEvent->set_direction(FunctionEvent::Entry);
595  FnEvent->set_strict(F.StrictMode);
596 
597  return ParseFunctionPredicate(FnEvent, Call, false, F);
598 }
599 
600 
601 bool Parser::ParseFunctionReturn(Expression *E, const CallExpr *Call, Flags F) {
602 
603  E->set_type(Expression::FUNCTION);
604 
605  FunctionEvent *FnEvent = E->mutable_function();
606  FnEvent->set_direction(FunctionEvent::Exit);
607  FnEvent->set_strict(F.StrictMode);
608 
609  return ParseFunctionPredicate(FnEvent, Call, true, F);
610 }
611 
612 
613 bool Parser::ParseCallee(Expression *E, const clang::CallExpr *Call, Flags F) {
614 
615  F.FnInstrContext = FunctionEvent::Callee;
616 
617  if (Call->getNumArgs() != 2) {
618  ReportError("expected two arguments: __tesla_ignore, expression", Call);
619  return false;
620  }
621 
622  return CheckIgnore(Call->getArg(0))
623  && Parse(E, Call->getArg(1), F);
624 }
625 
626 
627 bool Parser::ParseCaller(Expression *E, const clang::CallExpr *Call, Flags F) {
628 
629  F.FnInstrContext = FunctionEvent::Caller;
630 
631  if (Call->getNumArgs() != 2) {
632  ReportError("expected two arguments: __tesla_ignore, expression", Call);
633  return false;
634  }
635 
636  return CheckIgnore(Call->getArg(0))
637  && Parse(E, Call->getArg(1), F);
638 }
639 
640 
641 bool Parser::ParseStrictMode(Expression *E, const clang::CallExpr *Call,
642  Flags F) {
643 
644  if (Call->getNumArgs() != 2) {
645  ReportError("expected two arguments: __tesla_ignore, expression", Call);
646  return false;
647  }
648 
649  F.StrictMode = true;
650  return CheckIgnore(Call->getArg(0))
651  && Parse(E, Call->getArg(1), F);
652 }
653 
654 
655 bool Parser::ParseConditional(Expression *E, const clang::CallExpr *Call,
656  Flags F) {
657 
658  if (Call->getNumArgs() != 2) {
659  ReportError("expected two arguments: __tesla_ignore, expression", Call);
660  return false;
661  }
662 
663  F.StrictMode = false;
664  return CheckIgnore(Call->getArg(0))
665  && Parse(E, Call->getArg(1), F);
666 }
667 
668 
669 bool Parser::ParseFunctionPredicate(FunctionEvent *Event, const CallExpr *Call,
670  bool ParseRetVal, Flags F) {
671 
672  Event->set_context(F.FnInstrContext);
673 
674  // The arguments to __tesla_call/return are the function itself and then,
675  // optionally, the arguments (any of which may be __tesla_any()).
676  if (Call->getNumArgs() < 1) {
677  ReportError("missing function argument", Call);
678  return false;
679  }
680 
681  auto Arg = Call->getArg(0)->IgnoreParenCasts();
682  auto FnRef = dyn_cast<DeclRefExpr>(Arg);
683  // For C function calls
684  const FunctionDecl *Fn = 0;
685  // For Objective-C message sends
686  const ObjCMethodDecl *Meth = 0;
687 
688  const Expr *const*Args;
689  SmallVector<const Expr*, 8> ArgsVector;
690  int ArgCount = 0;
691 
692  if (FnRef) {
693  Args = Call->getArgs() + 1;
694  ArgCount = Call->getNumArgs() - 1;
695  } else
696  if (const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(Arg))
697  if (BinOp->getOpcode() == BO_Comma) {
698  Arg = BinOp->getLHS()->IgnoreParenCasts();
699  // IF this is just a function name (undecorated) then use it),
700  // otherwise get the call expression and look at it.
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();
705  }
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)) {
711  // If there isn't a direct callee, then we'll fall through to the
712  // error block. We probably should have a better error report
713  // here.
714  Fn = CE->getDirectCallee();
715  // Use this call as the call expression so that we can look at
716  // its arguments, and don't skip the first argument.
717  Args = CE->getArgs();
718  ArgCount = CE->getNumArgs();
719  } else if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(Arg)) {
720  Meth = OME->getMethodDecl();
721  if (!Meth) {
722  ReportError("types of Objective-C method to be instrumented must be known", OME);
723  return false;
724  }
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;
731  break;
732  case ObjCMessageExpr::Instance:
733  Parse(Event->mutable_receiver(), OME->getInstanceReceiver(), F);
734  kind = FunctionEvent::ObjCInstanceMessage;
735  break;
736  case ObjCMessageExpr::SuperClass:
737  case ObjCMessageExpr::SuperInstance:
738  kind = FunctionEvent::ObjCSuperMessage;
739  break;
740  }
741  Event->set_kind(kind);
742  Event->mutable_function()->set_name(Meth->getNameAsString());
743  Args = OME->getArgs();
744  ArgCount = OME->getNumArgs();
745  } else {
746  Call->dump();
747  assert(0);
748  }
749  // TODO: This is where ObjC / C++ method call expressions would be
750  // inspected.
751  }
752 
753  if (FnRef)
754  Fn = dyn_cast<FunctionDecl>(FnRef->getDecl());
755 
756  if (!(Fn || Meth)) {
757  ReportError("called() must refer to a function or method call", Call);
758  return false;
759  }
760 
761  bool HaveRetVal = ParseRetVal &&
762  (Fn ? !Fn->getResultType()->isVoidType()
763  : Meth->getResultType()->isVoidType()) ;
764 
765  // Parse the arguments to the event: either specified by the programmer in
766  // the assertion or else the definition of the function.
767 
768  if (ArgCount > 0) {
769  const size_t ExpectedSize = (Fn ? Fn->param_size() : Meth->param_size())
770  + (HaveRetVal ? 1 : 0);
771 
772  // If an assertion specifies any arguments, it must specify all of them.
773  if (ArgCount != ExpectedSize) {
774  ReportError("specify all args (possibly __tesla_any()) or none", Call);
775  return false;
776  }
777 
778  for (size_t i = 0; i < ArgCount; i++) {
779  if (!Parse(Event->add_argument(), Args[i], F))
780  return false;
781  }
782 
783  if (HaveRetVal)
784  { assert(0);
785  if (!Parse(Event->mutable_expectedreturnvalue(),
786  Args[ArgCount-1], F))
787  return false;
788  }
789 
790  } else {
791  // The assertion doesn't specify any arguments; include information about
792  // arguments from the function definition, just for information.
793  if (Fn)
794  for (auto I = Fn->param_begin(); I != Fn->param_end(); ++I) {
795  if (!Parse(Event->add_argument(), *I, true, F))
796  return false;
797  }
798  else
799  for (auto I = Meth->param_begin(); I != Meth->param_end(); ++I) {
800  if (!Parse(Event->add_argument(), *I, true, F))
801  return false;
802  }
803 
804 
805  if (HaveRetVal)
806  Event->mutable_expectedreturnvalue()->set_type(Argument::Any);
807  }
808 
809  return Fn ? Parse(Event->mutable_function(), Fn, F) : true;
810 }
811 
812 
813 bool Parser::ParseFieldAssign(Expression *E, const clang::BinaryOperator *O,
814  Flags F) {
815 
816  E->set_type(Expression::FIELD_ASSIGN);
817  FieldAssignment *A = E->mutable_fieldassign();
818  A->set_strict(F.StrictMode);
819 
820  switch (O->getOpcode()) {
821  default:
822  ReportError("unhandled compound assignment type", O);
823  return false;
824 
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;
828  }
829 
830  auto *LHS = dyn_cast<MemberExpr>(O->getLHS());
831  if (!LHS) {
832  ReportError("expected struct member", O);
833  return false;
834  }
835 
836  return CheckAssignmentKind(LHS->getMemberDecl(), O)
837  && ParseStructField(A->mutable_field(), LHS, F)
838  && Parse(A->mutable_value(), O->getRHS(), F);
839 }
840 
841 
842 bool Parser::ParseStructField(StructField *Field, const MemberExpr *ME,
843  Flags F) {
844  auto *Base =
845  dyn_cast<DeclRefExpr>(ME->getBase()->IgnoreImpCasts())->getDecl();
846 
847  auto BaseType = Base->getType();
848 
849  if (auto *BasePtrType = dyn_cast<PointerType>(BaseType))
850  BaseType = BasePtrType->getPointeeType();
851 
852  if (BaseType.isNull()) {
853  ReportError("base of assignment ME not a struct type", Base);
854  return false;
855  }
856 
857  Field->set_type(BaseType->getAsStructureType()->getDecl()->getName());
858 
859  auto *Member = dyn_cast<FieldDecl>(ME->getMemberDecl());
860  if (!Member) {
861  ReportError("struct member is not a FieldDecl", ME);
862  return false;
863  }
864 
865  Field->set_index(Member->getFieldIndex());
866  Field->set_name(Member->getName());
867 
868  return Parse(Field->mutable_base(), Base, false, F);
869 }
870 
871 
872 bool Parser::Parse(Argument *Arg, const Expr *E, Flags F) {
873  assert(Arg != NULL);
874  assert(E != NULL);
875 
876  auto P = E->IgnoreParenCasts();
877  llvm::APSInt ConstValue;
878 
879  // Each variable references must be one of:
880  // - a call to a TESLA pseudo-function:
881  // - __tesla_flags(),
882  // - __tesla_mask(),
883  // - __tesla_any*(),
884  // - a reference to a named declaration or
885  // - an integer constant expression.
886  if (auto Call = dyn_cast<CallExpr>(P)) {
887  auto Fn = Call->getDirectCallee();
888  if (!Fn) {
889  ReportError("expected TESLA predicate", P);
890  return false;
891  }
892 
893  StringRef Name = Fn->getName();
894 
895  if ((Name == FLAGS) || (Name == MASK)) {
896  if (Call->getNumArgs() != 1) {
897  ReportError("expected one argument", Call);
898  return false;
899  }
900 
901  Arg->set_constantmatch(
902  (Name == FLAGS) ? Argument::Flags : Argument::Mask);
903  P = Call->getArg(0);
904 
905  } else if (Name.slice(0, ANY.length()) == ANY) {
906  Arg->set_type(Argument::Any);
907  return true;
908 
909  } else {
910  ReportError("expected __tesla_{flags,mask,any}", P);
911  return false;
912  }
913 
914  }
915 
916  if (auto DRE = dyn_cast<DeclRefExpr>(P)) {
917  Arg->set_type(Argument::Variable);
918  const ValueDecl *D = DRE->getDecl();
919 
920  *Arg->mutable_name() = DRE->getDecl()->getName();
921  Arg->set_index(ReferenceIndex(D));
922  return true;
923  }
924 
925  if (P->isIntegerConstantExpr(ConstValue, Ctx)) {
926  Arg->set_type(Argument::Constant);
927  Arg->set_value(ConstValue.getSExtValue());
928 
929  // Find an appropriate string representation for the value.
930  SourceLocation Loc = P->getLocStart();
931  if (Loc.isMacroID()) {
932  //
933  // The constant's SourceLocation is within a macro; check if the macro
934  // represents the value itself (e.g. #define FOO 1) or if a literal
935  // happens to be written within a macro (e.g. TSEQUENCE(foo(12))).
936  //
937  // TODO(JA): understand and/or fix this:
938  // For reasons I don't understand, the most straightforward tests like
939  // SM.isAtStartOfImmediateMacroExpansion(Loc) or (Loc == SpellingLoc)
940  // don't tell us what we want to know: is the IntegerLiteral's value
941  // written in the same place as its spelling (within the code)?
942  //
943  // These two SouceLocation objects always seem to have different opaque
944  // internal values, but in the case we care about (where the value is
945  // actually given as a #defined macro), they point to the same raw
946  // character data from the relevant source file.
947  //
948  auto& SM = Ctx.getSourceManager();
949 
950  const char *RawCharData = SM.getCharacterData(Loc);
951  const char *SpellingCharData = SM.getCharacterData(
952  SM.getSLocEntry(SM.getFileID(Loc))
953  .getExpansion()
954  .getSpellingLoc());
955 
956  if (RawCharData == SpellingCharData)
957  *Arg->mutable_name() =
958  Lexer::getImmediateMacroName(Loc, SM, Ctx.getLangOpts());
959  }
960 
961  return true;
962  }
963 
964  // We also allow a very limited number of simple expressions:
965  // * multiple-return-via-pointer: foo(&x) => foo() returned x via pointer
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);
970  }
971  }
972 
973  // * structure field access: bar(s->x) => called bar() with s->x (TODO)
974  if (auto *ME = dyn_cast<MemberExpr>(P)) {
975  Arg->set_type(Argument::Field);
976  return ParseStructField(Arg->mutable_field(), ME, F);
977  }
978 
979  P->dump();
980  ReportError("Invalid argument to function within TESLA assertion", P);
981  return false;
982 }
983 
984 bool Parser::Parse(FunctionRef *FnRef, const FunctionDecl *Fn, Flags F) {
985  FnRef->set_name(Fn->getName());
986  if (FnRef->name().empty()) {
987  ReportError("Function must have a name", Fn);
988  return false;
989  }
990 
991  return true;
992 }
993 
994 
995 bool Parser::Parse(Argument *Arg, const ValueDecl *D, bool AllowAny, Flags F) {
996  assert(Arg != NULL);
997  assert(D != NULL);
998 
999  *Arg->mutable_name() = D->getName();
1000 
1001  if (AllowAny)
1002  Arg->set_type(Argument::Any);
1003  else {
1004  Arg->set_type(Argument::Variable);
1005  Arg->set_index(ReferenceIndex(D));
1006  }
1007 
1008  return true;
1009 }
1010 
1011 
1012 bool Parser::CheckIgnore(const Expr *E) {
1013  auto *IgnoreRef = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts());
1014  if (!IgnoreRef || IgnoreRef->getDecl()->getName() != IGNORE) {
1015  ReportError("expected " + IGNORE, E);
1016  E->dump();
1017  return false;
1018  }
1019 
1020  return true;
1021 }
1022 
1023 
1024 static inline bool SimpleAssignment(const Expr *E) {
1025  auto *BO = dyn_cast<BinaryOperator>(E);
1026  return (BO != NULL) && (BO->getOpcode() == BO_Assign);
1027 }
1028 
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;
1033  return true;
1034  }
1035 
1036  auto *Old = i->second;
1037 
1038  if (SimpleAssignment(E) == SimpleAssignment(Old))
1039  return true;
1040 
1041  static DiagnosticsEngine& Diag = Ctx.getDiagnostics();
1042  static int Warn = Diag.getCustomDiagID(DiagnosticsEngine::Warning,
1043  "TESLA: mixing instrumentation of simple and compound assignments");
1044 
1045  static int Note = Diag.getCustomDiagID(DiagnosticsEngine::Note,
1046  "TESLA: previous assignment here");
1047 
1048  Diag.Report(E->getLocStart(), Warn) << E->getSourceRange();
1049  Diag.Report(Old->getLocStart(), Note) << Old->getSourceRange();
1050 
1051  return false;
1052 }
1053 
1054 
1055 size_t Parser::ReferenceIndex(const ValueDecl* D) {
1056  size_t Pos = 0;
1057 
1058  for (auto I = References.begin(); I != References.end(); I++)
1059  if (*I == D)
1060  return Pos;
1061  else
1062  ++Pos;
1063 
1064  References.push_back(D);
1065 
1066  return Pos;
1067 }
1068 
1069 
1070 void Parser::ReportError(StringRef Message, const Decl *D) {
1071  ReportError(Message, D->getLocStart(), D->getSourceRange());
1072 }
1073 
1074 
1075 void Parser::ReportError(StringRef Message, const Stmt *S) {
1076  ReportError(Message, S->getLocStart(), S->getSourceRange());
1077 }
1078 
1079 
1080 void Parser::ReportError(StringRef Message, const SourceLocation& Start,
1081  const SourceRange& Range) {
1082 
1083  static const DiagnosticsEngine::Level Level = DiagnosticsEngine::Error;
1084 
1085  DiagnosticsEngine& Diag = Ctx.getDiagnostics();
1086  int DiagID = Diag.getCustomDiagID(Level, ("TESLA: " + Message).str());
1087 
1088  Diag.Report(Start, DiagID) << Range;
1089 }
1090 
1091 
1092 std::string Parser::ParseStringLiteral(const Expr* E) {
1093  auto LiteralValue = dyn_cast<StringLiteral>(E->IgnoreImplicit());
1094  if (!LiteralValue) {
1095  ReportError("expected string literal", E);
1096  return "";
1097  }
1098 
1099  return LiteralValue->getString();
1100 }
1101 
1102 
1103 llvm::APInt Parser::ParseIntegerLiteral(const Expr* E) {
1104  auto LiteralValue = dyn_cast<IntegerLiteral>(E->IgnoreImplicit());
1105  if (!LiteralValue) {
1106  ReportError("expected integer literal", E);
1107  return llvm::APInt();
1108  }
1109 
1110  return LiteralValue->getValue();
1111 }
1112