aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-02-18 05:49:11 +0000
committerChris Lattner <sabre@nondot.org>2009-02-18 05:49:11 +0000
commit726e168dc09fb23f53c7b004f8e919421ee91806 (patch)
tree31e28ff92e011dd2ffbc9bb0efdc83405749c99f
parentb103f01e5e2072c04ea5619c587a2b7ff2e63022 (diff)
change the StringLiteral AST node to track all of the SourceLocations of
the various PPTokens that are pasted together to make it. In the course of working on this, I discovered ParseObjCStringLiteral which needs some work. I'll tackle it next. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64892 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--Driver/RewriteObjC.cpp20
-rw-r--r--include/clang/AST/Expr.h25
-rw-r--r--lib/AST/Expr.cpp28
-rw-r--r--lib/AST/StmtSerialization.cpp10
-rw-r--r--lib/Sema/SemaExpr.cpp16
-rw-r--r--lib/Sema/SemaExprObjC.cpp13
6 files changed, 70 insertions, 42 deletions
diff --git a/Driver/RewriteObjC.cpp b/Driver/RewriteObjC.cpp
index 0674f8f116..878a94c1f1 100644
--- a/Driver/RewriteObjC.cpp
+++ b/Driver/RewriteObjC.cpp
@@ -1736,7 +1736,7 @@ Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) {
Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding);
Expr *Replacement = new (Context) StringLiteral(*Context,StrEncoding.c_str(),
StrEncoding.length(), false, StrType,
- SourceLocation(), SourceLocation());
+ SourceLocation());
ReplaceStmt(Exp, Replacement);
// Replace this subexpr in the parent.
@@ -1754,8 +1754,7 @@ Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
SelExprs.push_back(new (Context) StringLiteral((*Context),
Exp->getSelector().getAsString().c_str(),
Exp->getSelector().getAsString().size(),
- false, argType, SourceLocation(),
- SourceLocation()));
+ false, argType, SourceLocation()));
CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
&SelExprs[0], SelExprs.size());
ReplaceStmt(Exp, SelExp);
@@ -2293,8 +2292,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
ClsExprs.push_back(new (Context) StringLiteral(*Context,
SuperDecl->getIdentifier()->getName(),
SuperDecl->getIdentifier()->getLength(),
- false, argType, SourceLocation(),
- SourceLocation()));
+ false, argType, SourceLocation()));
CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
&ClsExprs[0],
ClsExprs.size());
@@ -2346,8 +2344,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
ClsExprs.push_back(new (Context) StringLiteral(*Context,
clsName->getName(),
clsName->getLength(),
- false, argType, SourceLocation(),
- SourceLocation()));
+ false, argType, SourceLocation()));
CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
&ClsExprs[0],
ClsExprs.size());
@@ -2377,8 +2374,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
ClsExprs.push_back(new (Context) StringLiteral(*Context,
SuperDecl->getIdentifier()->getName(),
SuperDecl->getIdentifier()->getLength(),
- false, argType, SourceLocation(),
- SourceLocation()));
+ false, argType, SourceLocation()));
CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
&ClsExprs[0],
ClsExprs.size());
@@ -2436,8 +2432,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
SelExprs.push_back(new (Context) StringLiteral(*Context,
Exp->getSelector().getAsString().c_str(),
Exp->getSelector().getAsString().size(),
- false, argType, SourceLocation(),
- SourceLocation()));
+ false, argType, SourceLocation()));
CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
&SelExprs[0], SelExprs.size());
MsgExprs.push_back(SelExp);
@@ -2605,8 +2600,7 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
StringLiteral(*Context,
Exp->getProtocol()->getNameAsCString(),
strlen(Exp->getProtocol()->getNameAsCString()),
- false, argType, SourceLocation(),
- SourceLocation()));
+ false, argType, SourceLocation()));
CallExpr *ProtoExp = SynthesizeCallToFunctionDecl(GetProtocolFunctionDecl,
&ProtoExprs[0],
ProtoExprs.size());
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index cb1400c079..8bd0c9d759 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -480,22 +480,33 @@ class StringLiteral : public Expr {
const char *StrData;
unsigned ByteLength;
bool IsWide;
- // if the StringLiteral was composed using token pasting, both locations
+ // If the StringLiteral was composed using token pasting, both locations
// are needed. If not (the common case), firstTokLoc == lastTokLoc.
- // FIXME: if space becomes an issue, we should create a sub-class.
- SourceLocation firstTokLoc, lastTokLoc;
+ unsigned NumConcatenated;
+ SourceLocation TokLocs[1];
public:
- StringLiteral(ASTContext& C, const char *strData, unsigned byteLength,
- bool Wide, QualType t, SourceLocation b, SourceLocation e);
+ StringLiteral(ASTContext &C, const char *StrData, unsigned ByteLength,
+ bool Wide, QualType t, SourceLocation Loc);
+ StringLiteral(ASTContext &C, const char *StrData, unsigned ByteLength,
+ bool Wide, QualType t, SourceLocation *Loc, unsigned NumStrs);
- void Destroy(ASTContext& C);
+ void Destroy(ASTContext &C);
const char *getStrData() const { return StrData; }
unsigned getByteLength() const { return ByteLength; }
bool isWide() const { return IsWide; }
+
+ /// getNumConcatenated - Get the number of string literal tokens that were
+ /// concatenated in translation phase #6 to form this string literal.
+ unsigned getNumConcatenated() const { return NumConcatenated; }
+
+ SourceLocation getStrTokenLoc(unsigned TokNum) const {
+ assert(TokNum < NumConcatenated && "Invalid tok number");
+ return TokLocs[TokNum];
+ }
virtual SourceRange getSourceRange() const {
- return SourceRange(firstTokLoc,lastTokLoc);
+ return SourceRange(TokLocs[0], TokLocs[NumConcatenated-1]);
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == StringLiteralClass;
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 0cd68ce3b8..81da44407b 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -39,20 +39,36 @@ double FloatingLiteral::getValueAsApproximateDouble() const {
StringLiteral::StringLiteral(ASTContext& C, const char *strData,
- unsigned byteLength, bool Wide, QualType t,
- SourceLocation firstLoc,
- SourceLocation lastLoc) :
- Expr(StringLiteralClass, t) {
+ unsigned byteLength, bool Wide, QualType Ty,
+ SourceLocation Loc) :
+ Expr(StringLiteralClass, Ty) {
// OPTIMIZE: could allocate this appended to the StringLiteral.
char *AStrData = new (C, 1) char[byteLength];
memcpy(AStrData, strData, byteLength);
StrData = AStrData;
ByteLength = byteLength;
IsWide = Wide;
- firstTokLoc = firstLoc;
- lastTokLoc = lastLoc;
+ TokLocs[0] = Loc;
+ NumConcatenated = 1;
}
+StringLiteral::StringLiteral(ASTContext &C, const char *strData,
+ unsigned byteLength, bool Wide, QualType Ty,
+ SourceLocation *Loc, unsigned NumStrs) :
+ Expr(StringLiteralClass, Ty) {
+ // OPTIMIZE: could allocate this appended to the StringLiteral.
+ char *AStrData = new (C, 1) char[byteLength];
+ memcpy(AStrData, strData, byteLength);
+ StrData = AStrData;
+ ByteLength = byteLength;
+ IsWide = Wide;
+ TokLocs[0] = Loc[0];
+ NumConcatenated = NumStrs;
+ if (NumStrs != 1)
+ memcpy(&TokLocs[1], Loc+1, sizeof(SourceLocation)*(NumStrs-1));
+}
+
+
void StringLiteral::Destroy(ASTContext &C) {
C.Deallocate(const_cast<char*>(StrData));
this->~StringLiteral();
diff --git a/lib/AST/StmtSerialization.cpp b/lib/AST/StmtSerialization.cpp
index 22ce8183fd..074969e9de 100644
--- a/lib/AST/StmtSerialization.cpp
+++ b/lib/AST/StmtSerialization.cpp
@@ -955,8 +955,7 @@ VAArgExpr* VAArgExpr::CreateImpl(llvm::Deserializer& D, ASTContext& C) {
void StringLiteral::EmitImpl(Serializer& S) const {
S.Emit(getType());
- S.Emit(firstTokLoc);
- S.Emit(lastTokLoc);
+ assert(0 && "Unimpl loc serialization");
S.EmitBool(isWide());
S.Emit(getByteLength());
@@ -966,13 +965,14 @@ void StringLiteral::EmitImpl(Serializer& S) const {
StringLiteral* StringLiteral::CreateImpl(Deserializer& D, ASTContext& C) {
QualType t = QualType::ReadVal(D);
- SourceLocation firstTokLoc = SourceLocation::ReadVal(D);
- SourceLocation lastTokLoc = SourceLocation::ReadVal(D);
+ assert(0 && "Unimpl loc serialization");
+ //SourceLocation firstTokLoc = SourceLocation::ReadVal(D);
+ //SourceLocation lastTokLoc = SourceLocation::ReadVal(D);
bool isWide = D.ReadBool();
unsigned ByteLength = D.ReadInt();
StringLiteral* sl = new (C, llvm::alignof<StringLiteral>())
- StringLiteral(C, NULL, 0, isWide, t, firstTokLoc, lastTokLoc);
+ StringLiteral(C, NULL, 0, isWide, t, SourceLocation());
char* StrData = new (C, llvm::alignof<char>()) char[ByteLength];
for (unsigned i = 0; i < ByteLength; ++i)
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 4eb29c4f94..c0b61bf8d7 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -352,13 +352,17 @@ Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) {
StrTy = Context.getConstantArrayType(StrTy,
llvm::APInt(32, Literal.GetStringLength()+1),
ArrayType::Normal, 0);
-
+ // Allocate enough space for the StringLiteral plus an array of locations for
+ // any concatenated strings.
+ void *Mem = Context.Allocate(sizeof(StringLiteral)+
+ sizeof(SourceLocation)*(NumStringToks-1));
+
// Pass &StringTokLocs[0], StringTokLocs.size() to factory!
- return Owned(new (Context) StringLiteral(Context, Literal.GetString(),
- Literal.GetStringLength(),
- Literal.AnyWide, StrTy,
- StringToks[0].getLocation(),
- StringToks[NumStringToks-1].getLocation()));
+ return Owned(new (Mem) StringLiteral(Context, Literal.GetString(),
+ Literal.GetStringLength(),
+ Literal.AnyWide, StrTy,
+ &StringTokLocs[0],
+ StringTokLocs.size()));
}
/// ShouldSnapshotBlockValueReference - Return true if a reference inside of
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 3e99482772..b0b5367790 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -29,10 +29,12 @@ Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
unsigned Length = 0;
for (unsigned i = 0; i < NumStrings; i++)
Length += static_cast<StringLiteral *>(Strings[i])->getByteLength();
- char *strBuf = new char [Length];
+
+ // FIXME: This should not be allocated by SEMA!
+ char *strBuf = new char[Length];
char *p = strBuf;
bool isWide = false;
- for (unsigned i = 0; i < NumStrings; i++) {
+ for (unsigned i = 0; i != NumStrings; ++i) {
S = static_cast<StringLiteral *>(Strings[i]);
if (S->isWide())
isWide = true;
@@ -40,9 +42,10 @@ Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
p += S->getByteLength();
S->Destroy(Context);
}
- S = new (Context, 8) StringLiteral(Context, strBuf, Length, isWide,
- Context.getPointerType(Context.CharTy),
- AtLoc, EndLoc);
+ // FIXME: PASS LOCATIONS PROPERLY.
+ S = new (Context) StringLiteral(Context, strBuf, Length, isWide,
+ Context.getPointerType(Context.CharTy),
+ AtLoc);
}
if (CheckBuiltinCFStringArgument(S))