зеркало из https://github.com/microsoft/clang-1.git
PCH support for string literals
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69172 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
c35d71f1e0
Коммит
673ecd6a4a
|
@ -581,12 +581,21 @@ public:
|
|||
return Create(C, StrData, ByteLength, Wide, Ty, &Loc, 1);
|
||||
}
|
||||
|
||||
/// \brief Construct an empty string literal.
|
||||
static StringLiteral *CreateEmpty(ASTContext &C, unsigned NumStrs);
|
||||
|
||||
StringLiteral* Clone(ASTContext &C) const;
|
||||
void Destroy(ASTContext &C);
|
||||
|
||||
const char *getStrData() const { return StrData; }
|
||||
unsigned getByteLength() const { return ByteLength; }
|
||||
|
||||
/// \brief Sets the string data to the given string data.
|
||||
void setStrData(ASTContext &C, const char *Str, unsigned Len);
|
||||
|
||||
bool isWide() const { return IsWide; }
|
||||
void setWide(bool W) { IsWide = W; }
|
||||
|
||||
bool containsNonAsciiOrNull() const {
|
||||
for (unsigned i = 0; i < getByteLength(); ++i)
|
||||
if (!isascii(getStrData()[i]) || !getStrData()[i])
|
||||
|
@ -601,7 +610,11 @@ public:
|
|||
assert(TokNum < NumConcatenated && "Invalid tok number");
|
||||
return TokLocs[TokNum];
|
||||
}
|
||||
|
||||
void setStrTokenLoc(unsigned TokNum, SourceLocation L) {
|
||||
assert(TokNum < NumConcatenated && "Invalid tok number");
|
||||
TokLocs[TokNum] = L;
|
||||
}
|
||||
|
||||
typedef const SourceLocation *tokloc_iterator;
|
||||
tokloc_iterator tokloc_begin() const { return TokLocs; }
|
||||
tokloc_iterator tokloc_end() const { return TokLocs+NumConcatenated; }
|
||||
|
|
|
@ -381,6 +381,8 @@ namespace clang {
|
|||
EXPR_INTEGER_LITERAL,
|
||||
/// \brief A FloatingLiteral record.
|
||||
EXPR_FLOATING_LITERAL,
|
||||
/// \brief A StringLiteral record.
|
||||
EXPR_STRING_LITERAL,
|
||||
/// \brief A CharacterLiteral record.
|
||||
EXPR_CHARACTER_LITERAL,
|
||||
/// \brief A ParenExpr record.
|
||||
|
|
|
@ -68,6 +68,17 @@ StringLiteral *StringLiteral::Create(ASTContext &C, const char *StrData,
|
|||
return SL;
|
||||
}
|
||||
|
||||
StringLiteral *StringLiteral::CreateEmpty(ASTContext &C, unsigned NumStrs) {
|
||||
void *Mem = C.Allocate(sizeof(StringLiteral)+
|
||||
sizeof(SourceLocation)*(NumStrs-1),
|
||||
llvm::alignof<StringLiteral>());
|
||||
StringLiteral *SL = new (Mem) StringLiteral(QualType());
|
||||
SL->StrData = 0;
|
||||
SL->ByteLength = 0;
|
||||
SL->NumConcatenated = NumStrs;
|
||||
return SL;
|
||||
}
|
||||
|
||||
StringLiteral* StringLiteral::Clone(ASTContext &C) const {
|
||||
return Create(C, StrData, ByteLength, IsWide, getType(),
|
||||
TokLocs, NumConcatenated);
|
||||
|
@ -79,6 +90,16 @@ void StringLiteral::Destroy(ASTContext &C) {
|
|||
C.Deallocate(this);
|
||||
}
|
||||
|
||||
void StringLiteral::setStrData(ASTContext &C, const char *Str, unsigned Len) {
|
||||
if (StrData)
|
||||
C.Deallocate(const_cast<char*>(StrData));
|
||||
|
||||
char *AStrData = new (C, 1) char[Len];
|
||||
memcpy(AStrData, Str, Len);
|
||||
StrData = AStrData;
|
||||
ByteLength = Len;
|
||||
}
|
||||
|
||||
/// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
|
||||
/// corresponds to, e.g. "sizeof" or "[pre]++".
|
||||
const char *UnaryOperator::getOpcodeStr(Opcode Op) {
|
||||
|
|
|
@ -226,6 +226,10 @@ namespace {
|
|||
unsigned &Idx, llvm::SmallVectorImpl<Expr *> &ExprStack)
|
||||
: Reader(Reader), Record(Record), Idx(Idx), ExprStack(ExprStack) { }
|
||||
|
||||
/// \brief The number of record fields required for the Expr class
|
||||
/// itself.
|
||||
static const unsigned NumExprFields = 3;
|
||||
|
||||
// Each of the Visit* functions reads in part of the expression
|
||||
// from the given record and the current expression stack, then
|
||||
// return the total number of operands that it read from the
|
||||
|
@ -236,6 +240,7 @@ namespace {
|
|||
unsigned VisitDeclRefExpr(DeclRefExpr *E);
|
||||
unsigned VisitIntegerLiteral(IntegerLiteral *E);
|
||||
unsigned VisitFloatingLiteral(FloatingLiteral *E);
|
||||
unsigned VisitStringLiteral(StringLiteral *E);
|
||||
unsigned VisitCharacterLiteral(CharacterLiteral *E);
|
||||
unsigned VisitParenExpr(ParenExpr *E);
|
||||
unsigned VisitUnaryOperator(UnaryOperator *E);
|
||||
|
@ -252,6 +257,7 @@ unsigned PCHStmtReader::VisitExpr(Expr *E) {
|
|||
E->setType(Reader.GetType(Record[Idx++]));
|
||||
E->setTypeDependent(Record[Idx++]);
|
||||
E->setValueDependent(Record[Idx++]);
|
||||
assert(Idx == NumExprFields && "Incorrect expression field count");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -284,6 +290,26 @@ unsigned PCHStmtReader::VisitFloatingLiteral(FloatingLiteral *E) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned PCHStmtReader::VisitStringLiteral(StringLiteral *E) {
|
||||
VisitExpr(E);
|
||||
unsigned Len = Record[Idx++];
|
||||
assert(Record[Idx] == E->getNumConcatenated() &&
|
||||
"Wrong number of concatenated tokens!");
|
||||
++Idx;
|
||||
E->setWide(Record[Idx++]);
|
||||
|
||||
// Read string data
|
||||
llvm::SmallVector<char, 16> Str(&Record[Idx], &Record[Idx] + Len);
|
||||
E->setStrData(Reader.getContext(), &Str[0], Len);
|
||||
Idx += Len;
|
||||
|
||||
// Read source locations
|
||||
for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
|
||||
E->setStrTokenLoc(I, SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned PCHStmtReader::VisitCharacterLiteral(CharacterLiteral *E) {
|
||||
VisitExpr(E);
|
||||
E->setValue(Record[Idx++]);
|
||||
|
@ -1656,6 +1682,11 @@ Expr *PCHReader::ReadExpr() {
|
|||
E = new (Context) FloatingLiteral(Empty);
|
||||
break;
|
||||
|
||||
case pch::EXPR_STRING_LITERAL:
|
||||
E = StringLiteral::CreateEmpty(Context,
|
||||
Record[PCHStmtReader::NumExprFields + 1]);
|
||||
break;
|
||||
|
||||
case pch::EXPR_CHARACTER_LITERAL:
|
||||
E = new (Context) CharacterLiteral(Empty);
|
||||
break;
|
||||
|
|
|
@ -448,6 +448,7 @@ namespace {
|
|||
void VisitDeclRefExpr(DeclRefExpr *E);
|
||||
void VisitIntegerLiteral(IntegerLiteral *E);
|
||||
void VisitFloatingLiteral(FloatingLiteral *E);
|
||||
void VisitStringLiteral(StringLiteral *E);
|
||||
void VisitCharacterLiteral(CharacterLiteral *E);
|
||||
void VisitParenExpr(ParenExpr *E);
|
||||
void VisitUnaryOperator(UnaryOperator *E);
|
||||
|
@ -495,6 +496,22 @@ void PCHStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
|
|||
Code = pch::EXPR_FLOATING_LITERAL;
|
||||
}
|
||||
|
||||
void PCHStmtWriter::VisitStringLiteral(StringLiteral *E) {
|
||||
VisitExpr(E);
|
||||
Record.push_back(E->getByteLength());
|
||||
Record.push_back(E->getNumConcatenated());
|
||||
Record.push_back(E->isWide());
|
||||
// FIXME: String data should be stored as a blob at the end of the
|
||||
// StringLiteral. However, we can't do so now because we have no
|
||||
// provision for coping with abbreviations when we're jumping around
|
||||
// the PCH file during deserialization.
|
||||
Record.insert(Record.end(),
|
||||
E->getStrData(), E->getStrData() + E->getByteLength());
|
||||
for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
|
||||
Writer.AddSourceLocation(E->getStrTokenLoc(I), Record);
|
||||
Code = pch::EXPR_STRING_LITERAL;
|
||||
}
|
||||
|
||||
void PCHStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
|
||||
VisitExpr(E);
|
||||
Record.push_back(E->getValue());
|
||||
|
|
|
@ -20,6 +20,11 @@ long_literal *long_ptr1 = &long_integer;
|
|||
// FloatingLiteral + ParenExpr
|
||||
floating_literal *double_ptr = &floating;
|
||||
|
||||
// StringLiteral
|
||||
const char* printHello() {
|
||||
return hello;
|
||||
}
|
||||
|
||||
// CharacterLiteral
|
||||
char_literal *int_ptr3 = &integer;
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@ typedef typeof(17l) long_literal;
|
|||
// FloatingLiteral and ParenExpr
|
||||
typedef typeof((42.5)) floating_literal;
|
||||
|
||||
// StringLiteral
|
||||
const char *hello = "Hello" "PCH" "World";
|
||||
|
||||
// CharacterLiteral
|
||||
typedef typeof('a') char_literal;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче