aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2007-10-15 02:50:23 +0000
committerAnders Carlsson <andersca@mac.com>2007-10-15 02:50:23 +0000
commitee98ac5a1330db432b188dd2d38b6631aac47bf1 (patch)
tree6401489c981418fc4d86e1099659645d179d4038
parent1ff8b58fa0fda7dd3a0a715637c2db2f9573539f (diff)
Add support for Pascal strings.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42974 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--AST/StmtPrinter.cpp2
-rw-r--r--Driver/clang.cpp6
-rw-r--r--Lex/LiteralSupport.cpp18
-rw-r--r--Sema/SemaExpr.cpp15
-rw-r--r--clang.xcodeproj/project.pbxproj1
-rw-r--r--include/clang/Basic/DiagnosticKinds.def2
-rw-r--r--include/clang/Basic/LangOptions.h4
-rw-r--r--include/clang/Lex/LiteralSupport.h1
8 files changed, 45 insertions, 4 deletions
diff --git a/AST/StmtPrinter.cpp b/AST/StmtPrinter.cpp
index 15582547c2..ff4b54bd8d 100644
--- a/AST/StmtPrinter.cpp
+++ b/AST/StmtPrinter.cpp
@@ -419,7 +419,7 @@ void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
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]) {
diff --git a/Driver/clang.cpp b/Driver/clang.cpp
index 6d9b6b0e46..6e8dd9e967 100644
--- a/Driver/clang.cpp
+++ b/Driver/clang.cpp
@@ -271,10 +271,15 @@ NoOperatorNames("fno-operator-names",
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.
@@ -325,6 +330,7 @@ static void InitializeLanguageStandard(LangOptions &Options) {
Options.Trigraphs = 1; // -trigraphs or -ansi
Options.DollarIdents = 1; // FIXME: Really a target property.
+ Options.PascalStrings = PascalStrings;
}
//===----------------------------------------------------------------------===//
diff --git a/Lex/LiteralSupport.cpp b/Lex/LiteralSupport.cpp
index 90a05f68b4..c0027f266c 100644
--- a/Lex/LiteralSupport.cpp
+++ b/Lex/LiteralSupport.cpp
@@ -599,6 +599,8 @@ StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
// 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
@@ -619,6 +621,19 @@ StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
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] != '\\') {
@@ -665,4 +680,7 @@ StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
for (unsigned i = 1, e = wchar_tByteWidth; i != e; ++i)
*ResultPtr++ = 0;
}
+
+ if (Pascal)
+ ResultBuf[0] = ResultPtr-&ResultBuf[0]-1;
}
diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp
index 904230f82c..471312baf0 100644
--- a/Sema/SemaExpr.cpp
+++ b/Sema/SemaExpr.cpp
@@ -46,11 +46,22 @@ Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) {
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());
}
diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj
index b88c381faa..75d938806b 100644
--- a/clang.xcodeproj/project.pbxproj
+++ b/clang.xcodeproj/project.pbxproj
@@ -742,6 +742,7 @@
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
+ compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
projectDirPath = "";
diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def
index 2a8900c025..e2b055b783 100644
--- a/include/clang/Basic/DiagnosticKinds.def
+++ b/include/clang/Basic/DiagnosticKinds.def
@@ -771,6 +771,8 @@ DIAG(err_typecheck_choose_expr_requires_constant, ERROR,
"'__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,
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index a2d07f0e44..afd91e2405 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -34,10 +34,12 @@ struct LangOptions {
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;
}
};
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index dde2d91976..e8650fc8fa 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -150,6 +150,7 @@ public:
Preprocessor &PP, TargetInfo &T);
bool hadError;
bool AnyWide;
+ bool Pascal;
const char *GetString() { return &ResultBuf[0]; }
unsigned GetStringLength() { return ResultPtr-&ResultBuf[0]; }