зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
b103f01e5e
Коммит
726e168dc0
|
@ -1736,7 +1736,7 @@ Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) {
|
||||||
Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding);
|
Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding);
|
||||||
Expr *Replacement = new (Context) StringLiteral(*Context,StrEncoding.c_str(),
|
Expr *Replacement = new (Context) StringLiteral(*Context,StrEncoding.c_str(),
|
||||||
StrEncoding.length(), false, StrType,
|
StrEncoding.length(), false, StrType,
|
||||||
SourceLocation(), SourceLocation());
|
SourceLocation());
|
||||||
ReplaceStmt(Exp, Replacement);
|
ReplaceStmt(Exp, Replacement);
|
||||||
|
|
||||||
// Replace this subexpr in the parent.
|
// Replace this subexpr in the parent.
|
||||||
|
@ -1754,8 +1754,7 @@ Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
|
||||||
SelExprs.push_back(new (Context) StringLiteral((*Context),
|
SelExprs.push_back(new (Context) StringLiteral((*Context),
|
||||||
Exp->getSelector().getAsString().c_str(),
|
Exp->getSelector().getAsString().c_str(),
|
||||||
Exp->getSelector().getAsString().size(),
|
Exp->getSelector().getAsString().size(),
|
||||||
false, argType, SourceLocation(),
|
false, argType, SourceLocation()));
|
||||||
SourceLocation()));
|
|
||||||
CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
|
CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
|
||||||
&SelExprs[0], SelExprs.size());
|
&SelExprs[0], SelExprs.size());
|
||||||
ReplaceStmt(Exp, SelExp);
|
ReplaceStmt(Exp, SelExp);
|
||||||
|
@ -2293,8 +2292,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
|
||||||
ClsExprs.push_back(new (Context) StringLiteral(*Context,
|
ClsExprs.push_back(new (Context) StringLiteral(*Context,
|
||||||
SuperDecl->getIdentifier()->getName(),
|
SuperDecl->getIdentifier()->getName(),
|
||||||
SuperDecl->getIdentifier()->getLength(),
|
SuperDecl->getIdentifier()->getLength(),
|
||||||
false, argType, SourceLocation(),
|
false, argType, SourceLocation()));
|
||||||
SourceLocation()));
|
|
||||||
CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
|
CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
|
||||||
&ClsExprs[0],
|
&ClsExprs[0],
|
||||||
ClsExprs.size());
|
ClsExprs.size());
|
||||||
|
@ -2346,8 +2344,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
|
||||||
ClsExprs.push_back(new (Context) StringLiteral(*Context,
|
ClsExprs.push_back(new (Context) StringLiteral(*Context,
|
||||||
clsName->getName(),
|
clsName->getName(),
|
||||||
clsName->getLength(),
|
clsName->getLength(),
|
||||||
false, argType, SourceLocation(),
|
false, argType, SourceLocation()));
|
||||||
SourceLocation()));
|
|
||||||
CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
|
CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
|
||||||
&ClsExprs[0],
|
&ClsExprs[0],
|
||||||
ClsExprs.size());
|
ClsExprs.size());
|
||||||
|
@ -2377,8 +2374,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
|
||||||
ClsExprs.push_back(new (Context) StringLiteral(*Context,
|
ClsExprs.push_back(new (Context) StringLiteral(*Context,
|
||||||
SuperDecl->getIdentifier()->getName(),
|
SuperDecl->getIdentifier()->getName(),
|
||||||
SuperDecl->getIdentifier()->getLength(),
|
SuperDecl->getIdentifier()->getLength(),
|
||||||
false, argType, SourceLocation(),
|
false, argType, SourceLocation()));
|
||||||
SourceLocation()));
|
|
||||||
CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
|
CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
|
||||||
&ClsExprs[0],
|
&ClsExprs[0],
|
||||||
ClsExprs.size());
|
ClsExprs.size());
|
||||||
|
@ -2436,8 +2432,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
|
||||||
SelExprs.push_back(new (Context) StringLiteral(*Context,
|
SelExprs.push_back(new (Context) StringLiteral(*Context,
|
||||||
Exp->getSelector().getAsString().c_str(),
|
Exp->getSelector().getAsString().c_str(),
|
||||||
Exp->getSelector().getAsString().size(),
|
Exp->getSelector().getAsString().size(),
|
||||||
false, argType, SourceLocation(),
|
false, argType, SourceLocation()));
|
||||||
SourceLocation()));
|
|
||||||
CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
|
CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
|
||||||
&SelExprs[0], SelExprs.size());
|
&SelExprs[0], SelExprs.size());
|
||||||
MsgExprs.push_back(SelExp);
|
MsgExprs.push_back(SelExp);
|
||||||
|
@ -2605,8 +2600,7 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
|
||||||
StringLiteral(*Context,
|
StringLiteral(*Context,
|
||||||
Exp->getProtocol()->getNameAsCString(),
|
Exp->getProtocol()->getNameAsCString(),
|
||||||
strlen(Exp->getProtocol()->getNameAsCString()),
|
strlen(Exp->getProtocol()->getNameAsCString()),
|
||||||
false, argType, SourceLocation(),
|
false, argType, SourceLocation()));
|
||||||
SourceLocation()));
|
|
||||||
CallExpr *ProtoExp = SynthesizeCallToFunctionDecl(GetProtocolFunctionDecl,
|
CallExpr *ProtoExp = SynthesizeCallToFunctionDecl(GetProtocolFunctionDecl,
|
||||||
&ProtoExprs[0],
|
&ProtoExprs[0],
|
||||||
ProtoExprs.size());
|
ProtoExprs.size());
|
||||||
|
|
|
@ -480,22 +480,33 @@ class StringLiteral : public Expr {
|
||||||
const char *StrData;
|
const char *StrData;
|
||||||
unsigned ByteLength;
|
unsigned ByteLength;
|
||||||
bool IsWide;
|
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.
|
// are needed. If not (the common case), firstTokLoc == lastTokLoc.
|
||||||
// FIXME: if space becomes an issue, we should create a sub-class.
|
unsigned NumConcatenated;
|
||||||
SourceLocation firstTokLoc, lastTokLoc;
|
SourceLocation TokLocs[1];
|
||||||
public:
|
public:
|
||||||
StringLiteral(ASTContext& C, const char *strData, unsigned byteLength,
|
StringLiteral(ASTContext &C, const char *StrData, unsigned ByteLength,
|
||||||
bool Wide, QualType t, SourceLocation b, SourceLocation e);
|
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; }
|
const char *getStrData() const { return StrData; }
|
||||||
unsigned getByteLength() const { return ByteLength; }
|
unsigned getByteLength() const { return ByteLength; }
|
||||||
bool isWide() const { return IsWide; }
|
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 {
|
virtual SourceRange getSourceRange() const {
|
||||||
return SourceRange(firstTokLoc,lastTokLoc);
|
return SourceRange(TokLocs[0], TokLocs[NumConcatenated-1]);
|
||||||
}
|
}
|
||||||
static bool classof(const Stmt *T) {
|
static bool classof(const Stmt *T) {
|
||||||
return T->getStmtClass() == StringLiteralClass;
|
return T->getStmtClass() == StringLiteralClass;
|
||||||
|
|
|
@ -39,20 +39,36 @@ double FloatingLiteral::getValueAsApproximateDouble() const {
|
||||||
|
|
||||||
|
|
||||||
StringLiteral::StringLiteral(ASTContext& C, const char *strData,
|
StringLiteral::StringLiteral(ASTContext& C, const char *strData,
|
||||||
unsigned byteLength, bool Wide, QualType t,
|
unsigned byteLength, bool Wide, QualType Ty,
|
||||||
SourceLocation firstLoc,
|
SourceLocation Loc) :
|
||||||
SourceLocation lastLoc) :
|
Expr(StringLiteralClass, Ty) {
|
||||||
Expr(StringLiteralClass, t) {
|
|
||||||
// OPTIMIZE: could allocate this appended to the StringLiteral.
|
// OPTIMIZE: could allocate this appended to the StringLiteral.
|
||||||
char *AStrData = new (C, 1) char[byteLength];
|
char *AStrData = new (C, 1) char[byteLength];
|
||||||
memcpy(AStrData, strData, byteLength);
|
memcpy(AStrData, strData, byteLength);
|
||||||
StrData = AStrData;
|
StrData = AStrData;
|
||||||
ByteLength = byteLength;
|
ByteLength = byteLength;
|
||||||
IsWide = Wide;
|
IsWide = Wide;
|
||||||
firstTokLoc = firstLoc;
|
TokLocs[0] = Loc;
|
||||||
lastTokLoc = lastLoc;
|
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) {
|
void StringLiteral::Destroy(ASTContext &C) {
|
||||||
C.Deallocate(const_cast<char*>(StrData));
|
C.Deallocate(const_cast<char*>(StrData));
|
||||||
this->~StringLiteral();
|
this->~StringLiteral();
|
||||||
|
|
|
@ -955,8 +955,7 @@ VAArgExpr* VAArgExpr::CreateImpl(llvm::Deserializer& D, ASTContext& C) {
|
||||||
|
|
||||||
void StringLiteral::EmitImpl(Serializer& S) const {
|
void StringLiteral::EmitImpl(Serializer& S) const {
|
||||||
S.Emit(getType());
|
S.Emit(getType());
|
||||||
S.Emit(firstTokLoc);
|
assert(0 && "Unimpl loc serialization");
|
||||||
S.Emit(lastTokLoc);
|
|
||||||
S.EmitBool(isWide());
|
S.EmitBool(isWide());
|
||||||
S.Emit(getByteLength());
|
S.Emit(getByteLength());
|
||||||
|
|
||||||
|
@ -966,13 +965,14 @@ void StringLiteral::EmitImpl(Serializer& S) const {
|
||||||
|
|
||||||
StringLiteral* StringLiteral::CreateImpl(Deserializer& D, ASTContext& C) {
|
StringLiteral* StringLiteral::CreateImpl(Deserializer& D, ASTContext& C) {
|
||||||
QualType t = QualType::ReadVal(D);
|
QualType t = QualType::ReadVal(D);
|
||||||
SourceLocation firstTokLoc = SourceLocation::ReadVal(D);
|
assert(0 && "Unimpl loc serialization");
|
||||||
SourceLocation lastTokLoc = SourceLocation::ReadVal(D);
|
//SourceLocation firstTokLoc = SourceLocation::ReadVal(D);
|
||||||
|
//SourceLocation lastTokLoc = SourceLocation::ReadVal(D);
|
||||||
bool isWide = D.ReadBool();
|
bool isWide = D.ReadBool();
|
||||||
unsigned ByteLength = D.ReadInt();
|
unsigned ByteLength = D.ReadInt();
|
||||||
|
|
||||||
StringLiteral* sl = new (C, llvm::alignof<StringLiteral>())
|
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];
|
char* StrData = new (C, llvm::alignof<char>()) char[ByteLength];
|
||||||
for (unsigned i = 0; i < ByteLength; ++i)
|
for (unsigned i = 0; i < ByteLength; ++i)
|
||||||
|
|
|
@ -352,13 +352,17 @@ Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) {
|
||||||
StrTy = Context.getConstantArrayType(StrTy,
|
StrTy = Context.getConstantArrayType(StrTy,
|
||||||
llvm::APInt(32, Literal.GetStringLength()+1),
|
llvm::APInt(32, Literal.GetStringLength()+1),
|
||||||
ArrayType::Normal, 0);
|
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!
|
// Pass &StringTokLocs[0], StringTokLocs.size() to factory!
|
||||||
return Owned(new (Context) StringLiteral(Context, Literal.GetString(),
|
return Owned(new (Mem) StringLiteral(Context, Literal.GetString(),
|
||||||
Literal.GetStringLength(),
|
Literal.GetStringLength(),
|
||||||
Literal.AnyWide, StrTy,
|
Literal.AnyWide, StrTy,
|
||||||
StringToks[0].getLocation(),
|
&StringTokLocs[0],
|
||||||
StringToks[NumStringToks-1].getLocation()));
|
StringTokLocs.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ShouldSnapshotBlockValueReference - Return true if a reference inside of
|
/// ShouldSnapshotBlockValueReference - Return true if a reference inside of
|
||||||
|
|
|
@ -29,10 +29,12 @@ Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
|
||||||
unsigned Length = 0;
|
unsigned Length = 0;
|
||||||
for (unsigned i = 0; i < NumStrings; i++)
|
for (unsigned i = 0; i < NumStrings; i++)
|
||||||
Length += static_cast<StringLiteral *>(Strings[i])->getByteLength();
|
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;
|
char *p = strBuf;
|
||||||
bool isWide = false;
|
bool isWide = false;
|
||||||
for (unsigned i = 0; i < NumStrings; i++) {
|
for (unsigned i = 0; i != NumStrings; ++i) {
|
||||||
S = static_cast<StringLiteral *>(Strings[i]);
|
S = static_cast<StringLiteral *>(Strings[i]);
|
||||||
if (S->isWide())
|
if (S->isWide())
|
||||||
isWide = true;
|
isWide = true;
|
||||||
|
@ -40,9 +42,10 @@ Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
|
||||||
p += S->getByteLength();
|
p += S->getByteLength();
|
||||||
S->Destroy(Context);
|
S->Destroy(Context);
|
||||||
}
|
}
|
||||||
S = new (Context, 8) StringLiteral(Context, strBuf, Length, isWide,
|
// FIXME: PASS LOCATIONS PROPERLY.
|
||||||
Context.getPointerType(Context.CharTy),
|
S = new (Context) StringLiteral(Context, strBuf, Length, isWide,
|
||||||
AtLoc, EndLoc);
|
Context.getPointerType(Context.CharTy),
|
||||||
|
AtLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CheckBuiltinCFStringArgument(S))
|
if (CheckBuiltinCFStringArgument(S))
|
||||||
|
|
Загрузка…
Ссылка в новой задаче