[analyzer] Add a utility method that allows to find the macro name used
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
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index 0c51ac5..eef5461 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -66,7 +66,11 @@
   ASTContext &getASTContext() {
     return Eng.getContext();
   }
-  
+
+  const LangOptions &getLangOptions() const {
+    return Eng.getContext().getLangOptions();
+  }
+
   const LocationContext *getLocationContext() const {
     return Pred->getLocationContext();
   }
@@ -161,6 +165,17 @@
   /// 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,
diff --git a/lib/StaticAnalyzer/Core/CheckerContext.cpp b/lib/StaticAnalyzer/Core/CheckerContext.cpp
index cb272fb..6aaa377 100644
--- a/lib/StaticAnalyzer/Core/CheckerContext.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerContext.cpp
@@ -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 @@
 
   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();
+}
+