CheckerContext.h revision 4e4d08403ca5cfd4d558fa2936215d3a4e5a528d
16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//== CheckerContext.h - Context info for path-sensitive checkers--*- C++ -*--=//
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                     The LLVM Compiler Infrastructure
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This file is distributed under the University of Illinois Open Source
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// License. See LICENSE.TXT for details.
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//===----------------------------------------------------------------------===//
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  This file defines CheckerContext that provides contextual info for
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// path-sensitive checkers.
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//===----------------------------------------------------------------------===//
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifndef LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennnamespace clang {
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennnamespace ento {
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennclass CheckerContext {
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ExprEngine &Eng;
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// The current exploded(symbolic execution) graph node.
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ExplodedNode *Pred;
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// The flag is true if the (state of the execution) has been modified
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// by the checker using this context. For example, a new transition has been
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// added or a bug report issued.
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool Changed;
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// The tagged location, which is used to generate all new nodes.
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const ProgramPoint Location;
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  NodeBuilder &NB;
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennpublic:
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  CheckerContext(NodeBuilder &builder,
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                 ExprEngine &eng,
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                 ExplodedNode *pred,
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                 const ProgramPoint &loc)
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    : Eng(eng),
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      Pred(pred),
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      Changed(false),
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      Location(loc),
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      NB(builder) {
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert(Pred->getState() &&
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           "We should not call the checkers on an empty state.");
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  AnalysisManager &getAnalysisManager() {
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Eng.getAnalysisManager();
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ConstraintManager &getConstraintManager() {
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Eng.getConstraintManager();
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  StoreManager &getStoreManager() {
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Eng.getStoreManager();
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// \brief Returns the previous node in the exploded graph, which includes
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// the state of the program before the checker ran. Note, checkers should
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// not retain the node in their state since the nodes might get invalidated.
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ExplodedNode *getPredecessor() { return Pred; }
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ProgramStateRef getState() const { return Pred->getState(); }
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// \brief Check if the checker changed the state of the execution; ex: added
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// a new transition or a bug report.
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isDifferent() { return Changed; }
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// \brief Returns the number of times the current block has been visited
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// along the analyzed path.
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  unsigned getCurrentBlockCount() const {
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return NB.getContext().getCurrentBlockCount();
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ASTContext &getASTContext() {
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Eng.getContext();
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const LangOptions &getLangOpts() const {
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Eng.getContext().getLangOpts();
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const LocationContext *getLocationContext() const {
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Pred->getLocationContext();
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  BugReporter &getBugReporter() {
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Eng.getBugReporter();
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  SourceManager &getSourceManager() {
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return getBugReporter().getSourceManager();
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  SValBuilder &getSValBuilder() {
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Eng.getSValBuilder();
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  SymbolManager &getSymbolManager() {
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return getSValBuilder().getSymbolManager();
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isObjCGCEnabled() const {
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Eng.isObjCGCEnabled();
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ProgramStateManager &getStateManager() {
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Eng.getStateManager();
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  AnalysisDeclContext *getCurrentAnalysisDeclContext() const {
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return Pred->getLocationContext()->getAnalysisDeclContext();
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// \brief Generates a new transition in the program state graph
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// (ExplodedGraph). Uses the default CheckerContext predecessor node.
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ///
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// @param State The state of the generated node.
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// @param Tag The tag is used to uniquely identify the creation site. If no
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ///        tag is specified, a default tag, unique to the given checker,
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ///        will be used. Tags are used to prevent states generated at
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ///        different sites from caching out.
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ExplodedNode *addTransition(ProgramStateRef State,
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              const ProgramPointTag *Tag = 0) {
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return addTransitionImpl(State, false, 0, Tag);
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// \brief Generates a default transition (containing checker tag but no
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// checker state changes).
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ExplodedNode *addTransition() {
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return addTransition(getState());
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// \brief Generates a new transition with the given predecessor.
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// Allows checkers to generate a chain of nodes.
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ///
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// @param State The state of the generated node.
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// @param Pred The transition will be generated from the specified Pred node
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ///             to the newly generated node.
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// @param Tag The tag to uniquely identify the creation site.
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// @param IsSink Mark the new node as sink, which will stop exploration of
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ///               the given path.
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ExplodedNode *addTransition(ProgramStateRef State,
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             ExplodedNode *Pred,
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             const ProgramPointTag *Tag = 0,
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             bool IsSink = false) {
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return addTransitionImpl(State, IsSink, Pred, Tag);
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// \brief Generate a sink node. Generating sink stops exploration of the
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// given path.
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ExplodedNode *generateSink(ProgramStateRef state = 0) {
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return addTransitionImpl(state ? state : getState(), true);
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// \brief Emit the diagnostics report.
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  void EmitReport(BugReport *R) {
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Changed = true;
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Eng.getBugReporter().EmitReport(R);
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// \brief Get the declaration of the called function (path-sensitive).
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  const FunctionDecl *getCalleeDecl(const CallExpr *CE) const;
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// \brief Get the name of the called function (path-sensitive).
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  StringRef getCalleeName(const FunctionDecl *FunDecl) const;
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// \brief Get the name of the called function (path-sensitive).
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  StringRef getCalleeName(const CallExpr *CE) const {
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const FunctionDecl *FunDecl = getCalleeDecl(CE);
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return getCalleeName(FunDecl);
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// Given a function declaration and a name checks if this is a C lib
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// function with the given name.
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name);
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  static bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name,
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 ASTContext &Context);
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// \brief Depending on wither the location corresponds to a macro, return
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// either the macro name or the token spelling.
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ///
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// This could be useful when checkers' logic depends on whether a function
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// is called with a given macro argument. For example:
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ///   s = socket(AF_INET,..)
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// If AF_INET is a macro, the result should be treated as a source of taint.
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ///
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  /// \sa clang::Lexer::getSpelling(), clang::Lexer::getImmediateMacroName().
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  StringRef getMacroNameOrSpelling(SourceLocation &Loc);
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennprivate:
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  ExplodedNode *addTransitionImpl(ProgramStateRef State,
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 bool MarkAsSink,
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 ExplodedNode *P = 0,
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 const ProgramPointTag *Tag = 0) {
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (!State || (State == Pred->getState() && !Tag && !MarkAsSink))
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      return Pred;
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Changed = true;
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ExplodedNode *node = NB.generateNode(Tag ? Location.withTag(Tag) : Location,
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        State,
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        P ? P : Pred, MarkAsSink);
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return node;
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  }
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/// \brief A helper class which wraps a boolean value set to false by default.
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstruct DefaultBool {
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  bool Val;
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  DefaultBool() : Val(false) {}
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  operator bool() const { return Val; }
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  DefaultBool &operator=(bool b) { Val = b; return *this; }
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // end GR namespace
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} // end clang namespace
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn