From: Anders Carlsson Date: Mon, 15 Oct 2007 02:50:23 +0000 (+0000) Subject: Add support for Pascal strings. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ee98ac5a1330db432b188dd2d38b6631aac47bf1;p=clang Add support for Pascal strings. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42974 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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 +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]; }