void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
if (Str->isWide()) OS << 'L';
OS << '"';
-
+
// FIXME: this doesn't print wstrings right.
for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
switch (Str->getStrData()[i]) {
llvm::cl::desc("Do not treat C++ operator name keywords as "
"synonyms for operators"));
+static llvm::cl::opt<bool>
+PascalStrings("fpascal-strings",
+ llvm::cl::desc("Recognize and construct Pascal-style "
+ "string literals"));
// FIXME: add:
// -ansi
// -trigraphs
// -fdollars-in-identifiers
+// -fpascal-strings
static void InitializeLanguageStandard(LangOptions &Options) {
if (LangStd == lang_unspecified) {
// Based on the base language, pick one.
Options.Trigraphs = 1; // -trigraphs or -ansi
Options.DollarIdents = 1; // FIXME: Really a target property.
+ Options.PascalStrings = PascalStrings;
}
//===----------------------------------------------------------------------===//
// wide strings as appropriate.
ResultPtr = &ResultBuf[0]; // Next byte to fill in.
+ Pascal = false;
+
for (unsigned i = 0, e = NumStringToks; i != e; ++i) {
const char *ThisTokBuf = &TokenBuf[0];
// Get the spelling of the token, which eliminates trigraphs, etc. We know
assert(ThisTokBuf[0] == '"' && "Expected quote, lexer broken?");
++ThisTokBuf;
+ // Check if this is a pascal string
+ if (pp.getLangOptions().PascalStrings && ThisTokBuf + 1 != ThisTokEnd &&
+ ThisTokBuf[0] == '\\' && ThisTokBuf[1] == 'p') {
+
+ // If the \p sequence is found in the first token, we have a pascal string
+ // Otherwise, if we already have a pascal string, ignore the first \p
+ if (i == 0) {
+ ++ThisTokBuf;
+ Pascal = true;
+ } else if (Pascal)
+ ThisTokBuf += 2;
+ }
+
while (ThisTokBuf != ThisTokEnd) {
// Is this a span of non-escape characters?
if (ThisTokBuf[0] != '\\') {
for (unsigned i = 1, e = wchar_tByteWidth; i != e; ++i)
*ResultPtr++ = 0;
}
+
+ if (Pascal)
+ ResultBuf[0] = ResultPtr-&ResultBuf[0]-1;
}
StringTokLocs.push_back(StringToks[i].getLocation());
// FIXME: handle wchar_t
- QualType t = Context.getPointerType(Context.CharTy);
+ QualType t;
+
+ if (Literal.Pascal)
+ t = Context.getPointerType(Context.UnsignedCharTy);
+ else
+ t = Context.getPointerType(Context.CharTy);
+
+ if (Literal.Pascal && Literal.GetStringLength() > 256)
+ return Diag(StringToks[0].getLocation(), diag::err_pascal_string_too_long,
+ SourceRange(StringToks[0].getLocation(),
+ StringToks[NumStringToks-1].getLocation()));
// Pass &StringTokLocs[0], StringTokLocs.size() to factory!
return new StringLiteral(Literal.GetString(), Literal.GetStringLength(),
- Literal.AnyWide, t, StringToks[0].getLocation(),
+ Literal.AnyWide, t,
+ StringToks[0].getLocation(),
StringToks[NumStringToks-1].getLocation());
}
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
+ compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
projectDirPath = "";
"'__builtin_choose_expr' requires a constant expression")
DIAG(warn_unused_expr, WARNING,
"expression result unused")
+DIAG(err_pascal_string_too_long, ERROR,
+ "Pascal string is too long")
// CHECK: printf format string errors
DIAG(warn_printf_not_string_constant, WARNING,
unsigned ObjC1 : 1; // Objective C 1 support enabled.
unsigned ObjC2 : 1; // Objective C 2 support enabled.
+ unsigned PascalStrings : 1; // Allow Pascal strings
+
LangOptions() {
Trigraphs = BCPLComment = DollarIdents = Digraphs = ObjC1 = ObjC2 = 0;
C99 = Microsoft = CPlusPlus = CPlusPlus0x = NoExtensions = 0;
- CXXOperatorNames = 0;
+ CXXOperatorNames = PascalStrings = 0;
}
};
Preprocessor &PP, TargetInfo &T);
bool hadError;
bool AnyWide;
+ bool Pascal;
const char *GetString() { return &ResultBuf[0]; }
unsigned GetStringLength() { return ResultPtr-&ResultBuf[0]; }