[cfe-commits] r127221 - in /cfe/trunk: include/clang/Lex/Lexer.h include/clang/Lex/Preprocessor.h include/clang/Sema/Sema.h lib/Lex/Lexer.cpp lib/Lex/Preprocessor.cpp lib/Sema/Sema.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaType.cpp test/SemaObjC/attr-objc-gc.m

John McCall rjmccall at apple.com
Mon Mar 7 23:59:04 PST 2011


Author: rjmccall
Date: Tue Mar  8 01:59:04 2011
New Revision: 127221

URL: http://llvm.org/viewvc/llvm-project?rev=127221&view=rev
Log:
Fix my earlier commit to work with escaped newlines and leave breadcrumbs
in case we want to make a world where we can check intermediate instantiations
for this kind of breadcrumb.


Modified:
    cfe/trunk/include/clang/Lex/Lexer.h
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Lex/Lexer.cpp
    cfe/trunk/lib/Lex/Preprocessor.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/SemaObjC/attr-objc-gc.m

Modified: cfe/trunk/include/clang/Lex/Lexer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Lexer.h?rev=127221&r1=127220&r2=127221&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Lexer.h (original)
+++ cfe/trunk/include/clang/Lex/Lexer.h Tue Mar  8 01:59:04 2011
@@ -236,6 +236,20 @@
                                  const SourceManager &SourceMgr,
                                  const LangOptions &Features, 
                                  bool *Invalid = 0);
+
+  /// getSpelling - This method is used to get the spelling of the
+  /// token at the given source location.  If, as is usually true, it
+  /// is not necessary to copy any data, then the returned string may
+  /// not point into the provided buffer.
+  ///
+  /// This method lexes at the instantiation depth of the given
+  /// location and does not jump to the instantiation or spelling
+  /// location.
+  static llvm::StringRef getSpelling(SourceLocation loc,
+                                     llvm::SmallVectorImpl<char> &buffer,
+                                     const SourceManager &SourceMgr,
+                                     const LangOptions &Features,
+                                     bool *invalid = 0);
   
   /// MeasureTokenLength - Relex the token at the specified location and return
   /// its length in bytes in the input file.  If the token needs cleaning (e.g.

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=127221&r1=127220&r2=127221&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Tue Mar  8 01:59:04 2011
@@ -644,10 +644,18 @@
     return Diags->Report(Tok.getLocation(), DiagID);
   }
 
-  /// getSpelling() - Return the 'spelling' of the token at the given location.
+  /// getSpelling() - Return the 'spelling' of the token at the given
+  /// location; does not go up to the spelling location or down to the
+  /// instantiation location.
   ///
+  /// \param buffer A buffer which will be used only if the token requires
+  ///   "cleaning", e.g. if it contains trigraphs or escaped newlines
   /// \param invalid If non-null, will be set \c true if an error occurs.
-  llvm::StringRef getSpelling(SourceLocation loc, bool *invalid = 0) const;
+  llvm::StringRef getSpelling(SourceLocation loc,
+                              llvm::SmallVectorImpl<char> &buffer,
+                              bool *invalid = 0) const {
+    return Lexer::getSpelling(loc, buffer, SourceMgr, Features, invalid);
+  }
 
   /// getSpelling() - Return the 'spelling' of the Tok token.  The spelling of a
   /// token is the characters used to represent the token in the source file

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=127221&r1=127220&r2=127221&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Mar  8 01:59:04 2011
@@ -678,6 +678,8 @@
   /// \brief Build a partial diagnostic.
   PartialDiagnostic PDiag(unsigned DiagID = 0); // in SemaInternal.h
 
+  bool findMacroSpelling(SourceLocation &loc, llvm::StringRef name);
+
   ExprResult Owned(Expr* E) { return E; }
   ExprResult Owned(ExprResult R) { return R; }
   StmtResult Owned(Stmt* S) { return S; }
@@ -1704,6 +1706,7 @@
   /// initialization.
   void CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI,
                                   llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
+
   //===--------------------------------------------------------------------===//
   // Statement Parsing Callbacks: SemaStmt.cpp.
 public:

Modified: cfe/trunk/lib/Lex/Lexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=127221&r1=127220&r2=127221&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Lexer.cpp (original)
+++ cfe/trunk/lib/Lex/Lexer.cpp Tue Mar  8 01:59:04 2011
@@ -221,6 +221,54 @@
 /// after trigraph expansion and escaped-newline folding.  In particular, this
 /// wants to get the true, uncanonicalized, spelling of things like digraphs
 /// UCNs, etc.
+llvm::StringRef Lexer::getSpelling(SourceLocation loc,
+                                   llvm::SmallVectorImpl<char> &buffer,
+                                   const SourceManager &SM,
+                                   const LangOptions &options,
+                                   bool *invalid) {
+  // Break down the source location.
+  std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc);
+
+  // Try to the load the file buffer.
+  bool invalidTemp = false;
+  llvm::StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
+  if (invalidTemp) {
+    if (invalid) *invalid = true;
+    return llvm::StringRef();
+  }
+
+  const char *tokenBegin = file.data() + locInfo.second;
+
+  // Lex from the start of the given location.
+  Lexer lexer(SM.getLocForStartOfFile(locInfo.first), options,
+              file.begin(), tokenBegin, file.end());
+  Token token;
+  lexer.LexFromRawLexer(token);
+
+  unsigned length = token.getLength();
+
+  // Common case:  no need for cleaning.
+  if (!token.needsCleaning())
+    return llvm::StringRef(tokenBegin, length);
+  
+  // Hard case, we need to relex the characters into the string.
+  buffer.clear();
+  buffer.reserve(length);
+  
+  for (const char *ti = tokenBegin, *te = ti + length; ti != te; ) {
+    unsigned charSize;
+    buffer.push_back(Lexer::getCharAndSizeNoWarn(ti, charSize, options));
+    ti += charSize;
+  }
+
+  return llvm::StringRef(buffer.data(), buffer.size());
+}
+
+/// getSpelling() - Return the 'spelling' of this token.  The spelling of a
+/// token are the characters used to represent the token in the source file
+/// after trigraph expansion and escaped-newline folding.  In particular, this
+/// wants to get the true, uncanonicalized, spelling of things like digraphs
+/// UCNs, etc.
 std::string Lexer::getSpelling(const Token &Tok, const SourceManager &SourceMgr,
                                const LangOptions &Features, bool *Invalid) {
   assert((int)Tok.getLength() >= 0 && "Token character range is bogus!");

Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=127221&r1=127220&r2=127221&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Tue Mar  8 01:59:04 2011
@@ -278,17 +278,6 @@
     CodeComplete->CodeCompleteNaturalLanguage();
 }
 
-llvm::StringRef Preprocessor::getSpelling(SourceLocation loc,
-                                          bool *invalid) const {
-  bool invalidTemp = false;
-  if (!invalid) invalid = &invalidTemp;
-  const char *begin = SourceMgr.getCharacterData(loc, invalid);
-  if (*invalid) return llvm::StringRef();
-
-  unsigned length = Lexer::MeasureTokenLength(loc, SourceMgr, Features);
-  return llvm::StringRef(begin, length);
-}
-
 /// getSpelling - This method is used to get the spelling of a token into a
 /// SmallVector. Note that the returned StringRef may not point to the
 /// supplied buffer if a copy can be avoided.

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=127221&r1=127220&r2=127221&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Tue Mar  8 01:59:04 2011
@@ -592,6 +592,27 @@
   return Builder;
 }
 
+/// \brief Looks through the macro-instantiation chain for the given
+/// location, looking for a macro instantiation with the given name.
+/// If one is found, returns true and sets the location to that
+/// instantiation loc.
+bool Sema::findMacroSpelling(SourceLocation &locref, llvm::StringRef name) {
+  SourceLocation loc = locref;
+  if (!loc.isMacroID()) return false;
+
+  // There's no good way right now to look at the intermediate
+  // instantiations, so just jump to the instantiation location.
+  loc = getSourceManager().getInstantiationLoc(loc);
+
+  // If that's written with the name, stop here.
+  llvm::SmallVector<char, 16> buffer;
+  if (getPreprocessor().getSpelling(loc, buffer) == name) {
+    locref = loc;
+    return true;
+  }
+  return false;
+}
+
 /// \brief Determines the active Scope associated with the given declaration
 /// context.
 ///

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=127221&r1=127220&r2=127221&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Mar  8 01:59:04 2011
@@ -5261,9 +5261,8 @@
     // In this case, check to make sure that we got here from a "NULL"
     // string in the source code.
     NullExpr = NullExpr->IgnoreParenImpCasts();
-    SourceLocation Loc =
-      getSourceManager().getInstantiationLoc(NullExpr->getExprLoc());
-    if (getPreprocessor().getSpelling(Loc) != "NULL")
+    SourceLocation loc = NullExpr->getExprLoc();
+    if (!findMacroSpelling(loc, "NULL"))
       return false;
   }
 

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=127221&r1=127220&r2=127221&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Tue Mar  8 01:59:04 2011
@@ -95,12 +95,10 @@
 
   // The GC attributes are usually written with macros;  special-case them.
   if (useInstantiationLoc && loc.isMacroID() && attr.getParameterName()) {
-    SourceLocation instLoc = S.getSourceManager().getInstantiationLoc(loc);
-    llvm::StringRef macro = S.getPreprocessor().getSpelling(instLoc);
-    if ((macro == "__strong" && attr.getParameterName()->isStr("strong")) ||
-        (macro == "__weak" && attr.getParameterName()->isStr("weak"))) {
-      loc = instLoc;
-      name = macro;
+    if (attr.getParameterName()->isStr("strong")) {
+      if (S.findMacroSpelling(loc, "__strong")) name = "__strong";
+    } else if (attr.getParameterName()->isStr("weak")) {
+      if (S.findMacroSpelling(loc, "__weak")) name = "__weak";
     }
   }
 

Modified: cfe/trunk/test/SemaObjC/attr-objc-gc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-objc-gc.m?rev=127221&r1=127220&r2=127221&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/attr-objc-gc.m (original)
+++ cfe/trunk/test/SemaObjC/attr-objc-gc.m Tue Mar  8 01:59:04 2011
@@ -10,3 +10,10 @@
 static int __attribute__((objc_gc(weak))) g; // expected-warning {{'objc_gc' only applies to pointer types; type here is 'int'}}
 
 static __weak int h; // expected-warning {{'__weak' only applies to pointer types; type here is 'int'}}
+
+// TODO: it would be great if this reported as __weak
+#define WEAK __weak
+static WEAK int h; // expected-warning {{'objc_gc' only applies to pointer types; type here is 'int'}}
+
+/* expected-warning {{'__weak' only applies to pointer types; type here is 'int'}}*/ static __we\
+ak int i;





More information about the cfe-commits mailing list