[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