]> granicus.if.org Git - clang/commitdiff
[analyzer] Add a utility method that allows to find the macro name used
authorAnna Zaks <ganna@apple.com>
Fri, 20 Jan 2012 00:11:12 +0000 (00:11 +0000)
committerAnna Zaks <ganna@apple.com>
Fri, 20 Jan 2012 00:11:12 +0000 (00:11 +0000)
at the given location.

This could be useful when checkers' logic depends on whether a function
is called with a given macro argument.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148516 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
lib/StaticAnalyzer/Core/CheckerContext.cpp

index 0c51ac538ff7fab4bba5c02b4a7efaf5e31fefeb..eef5461f2d95e691868c40ed63c4c3506c90c198 100644 (file)
@@ -66,7 +66,11 @@ public:
   ASTContext &getASTContext() {
     return Eng.getContext();
   }
-  
+
+  const LangOptions &getLangOptions() const {
+    return Eng.getContext().getLangOptions();
+  }
+
   const LocationContext *getLocationContext() const {
     return Pred->getLocationContext();
   }
@@ -161,6 +165,17 @@ public:
   /// function with the given name.
   bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name);
 
+  /// \brief Depending on wither the location corresponds to a macro, return 
+  /// either the macro name or the token spelling.
+  ///
+  /// This could be useful when checkers' logic depends on whether a function
+  /// is called with a given macro argument. For example:
+  ///   s = socket(AF_INET,..)
+  /// If AF_INET is a macro, the result should be treated as a source of taint.
+  ///
+  /// \sa clang::Lexer::getSpelling(), clang::Lexer::getImmediateMacroName().
+  StringRef getMacroNameOrSpelling(SourceLocation &Loc);
+
 private:
   ExplodedNode *addTransitionImpl(const ProgramState *State,
                                  bool MarkAsSink,
index cb272fb1c3370dd1549d8a012126c09cff224d4a..6aaa3773259155e7dbf540592814c6aca0d16501 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/Basic/Builtins.h"
+#include "clang/Lex/Lexer.h"
 
 using namespace clang;
 using namespace ento;
@@ -53,3 +54,15 @@ bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD,
 
   return false;
 }
+
+StringRef CheckerContext::getMacroNameOrSpelling(SourceLocation &Loc) {
+  if (!Loc.isMacroID()) {
+    SmallVector<char, 16> buf;
+    return Lexer::getSpelling(Loc, buf, getSourceManager(), getLangOptions());
+  } else {
+    return Lexer::getImmediateMacroName(Loc, getSourceManager(),
+                                             getLangOptions());
+  }
+  return StringRef();
+}
+