[cfe-commits] r41136 - in /cfe/trunk: AST/ASTContext.cpp AST/Builtins.cpp Sema/Sema.h Sema/SemaChecking.cpp Sema/SemaExpr.cpp include/clang/AST/ASTContext.h include/clang/AST/Builtins.def include/clang/Basic/DiagnosticKinds.def test/Sema/cfstring.c
Anders Carlsson
andersca at mac.com
Thu Aug 16 22:31:47 PDT 2007
Author: andersca
Date: Fri Aug 17 00:31:46 2007
New Revision: 41136
URL: http://llvm.org/viewvc/llvm-project?rev=41136&view=rev
Log:
Add initial support for constant CFStrings.
Added:
cfe/trunk/test/Sema/cfstring.c
Modified:
cfe/trunk/AST/ASTContext.cpp
cfe/trunk/AST/Builtins.cpp
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaChecking.cpp
cfe/trunk/Sema/SemaExpr.cpp
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/Builtins.def
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/ASTContext.cpp?rev=41136&r1=41135&r2=41136&view=diff
==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Fri Aug 17 00:31:46 2007
@@ -740,3 +740,32 @@
return signedType;
}
}
+
+// getCFConstantStringType - Return the type used for constant CFStrings.
+QualType ASTContext::getCFConstantStringType() {
+ if (!CFConstantStringTypeDecl) {
+ CFConstantStringTypeDecl = new RecordDecl(Decl::Struct, SourceLocation(),
+ &Idents.get("__builtin_CFString"),
+ 0);
+
+ QualType FieldTypes[4];
+
+ // const int *isa;
+ FieldTypes[0] = getPointerType(IntTy.getQualifiedType(QualType::Const));
+ // int flags;
+ FieldTypes[1] = IntTy;
+ // const char *str;
+ FieldTypes[2] = getPointerType(CharTy.getQualifiedType(QualType::Const));
+ // long length;
+ FieldTypes[3] = LongTy;
+ // Create fields
+ FieldDecl *FieldDecls[4];
+
+ for (unsigned i = 0; i < 4; ++i)
+ FieldDecls[i] = new FieldDecl(SourceLocation(), 0, FieldTypes[i], 0);
+
+ CFConstantStringTypeDecl->defineBody(FieldDecls, 4);
+ }
+
+ return getTagDeclType(CFConstantStringTypeDecl);
+}
Modified: cfe/trunk/AST/Builtins.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Builtins.cpp?rev=41136&r1=41135&r2=41136&view=diff
==============================================================================
--- cfe/trunk/AST/Builtins.cpp (original)
+++ cfe/trunk/AST/Builtins.cpp Fri Aug 17 00:31:46 2007
@@ -84,34 +84,71 @@
}
}
+ QualType Type;
+
// Read the base type.
switch (*Str++) {
default: assert(0 && "Unknown builtin type letter!");
case 'v':
assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'v'!");
- return Context.VoidTy;
+ Type = Context.VoidTy;
+ break;
case 'f':
assert(!Long && !Signed && !Unsigned && "Bad modifiers used with 'f'!");
- return Context.FloatTy;
+ Type = Context.FloatTy;
+ break;
case 'd':
assert(!LongLong && !Signed && !Unsigned && "Bad modifiers used with 'd'!");
if (Long)
- return Context.LongDoubleTy;
- return Context.DoubleTy;
+ Type = Context.LongDoubleTy;
+ else
+ Type = Context.DoubleTy;
+ break;
case 's':
assert(!LongLong && "Bad modifiers used with 's'!");
if (Unsigned)
- return Context.UnsignedShortTy;
- return Context.ShortTy;
+ Type = Context.UnsignedShortTy;
+ else
+ Type = Context.ShortTy;
+ break;
case 'i':
if (Long)
- return Unsigned ? Context.UnsignedLongTy : Context.LongTy;
- if (LongLong)
- return Unsigned ? Context.UnsignedLongLongTy : Context.LongLongTy;
- if (Unsigned)
- return Context.UnsignedIntTy;
- return Context.IntTy; // default is signed.
+ Type = Unsigned ? Context.UnsignedLongTy : Context.LongTy;
+ else if (LongLong)
+ Type = Unsigned ? Context.UnsignedLongLongTy : Context.LongLongTy;
+ else if (Unsigned)
+ Type = Context.UnsignedIntTy;
+ else
+ Type = Context.IntTy; // default is signed.
+ break;
+ case 'c':
+ assert(!Long && !LongLong && "Bad modifiers used with 'c'!");
+ if (Signed)
+ Type = Context.SignedCharTy;
+ else if (Unsigned)
+ Type = Context.UnsignedCharTy;
+ else
+ Type = Context.CharTy;
+ break;
+ case 'F':
+ Type = Context.getCFConstantStringType();
+ break;
+ }
+
+ Done = false;
+ while (!Done) {
+ switch (*Str++) {
+ default: Done = true; --Str; break;
+ case '*':
+ Type = Context.getPointerType(Type);
+ break;
+ case 'C':
+ Type = Type.getQualifiedType(QualType::Const);
+ break;
+ }
}
+
+ return Type;
}
/// GetBuiltinType - Return the type for the specified builtin.
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=41136&r1=41135&r2=41136&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Fri Aug 17 00:31:46 2007
@@ -423,7 +423,7 @@
// Extra semantic analysis beyond the C type system
private:
- void CheckFunctionCall(Expr *Fn,
+ bool CheckFunctionCall(Expr *Fn,
SourceLocation LParenLoc, SourceLocation RParenLoc,
FunctionDecl *FDecl,
Expr** Args, unsigned NumArgsInCall);
@@ -433,6 +433,8 @@
bool HasVAListArg, FunctionDecl *FDecl,
unsigned format_idx, Expr** Args,
unsigned NumArgsInCall);
+
+ bool CheckBuiltinCFStringArgument(Expr* Arg);
};
Modified: cfe/trunk/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaChecking.cpp?rev=41136&r1=41135&r2=41136&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/Sema/SemaChecking.cpp Fri Aug 17 00:31:46 2007
@@ -28,7 +28,7 @@
/// CheckFunctionCall - Check a direct function call for various correctness
/// and safety properties not strictly enforced by the C type system.
-void
+bool
Sema::CheckFunctionCall(Expr *Fn,
SourceLocation LParenLoc, SourceLocation RParenLoc,
FunctionDecl *FDecl,
@@ -37,10 +37,17 @@
// Get the IdentifierInfo* for the called function.
IdentifierInfo *FnInfo = FDecl->getIdentifier();
+ if (FnInfo->getBuiltinID() ==
+ Builtin::BI__builtin___CFStringMakeConstantString) {
+ assert(NumArgsInCall == 1 &&
+ "Wrong number of arguments to builtin CFStringMakeConstantString");
+ return CheckBuiltinCFStringArgument(Args[0]);
+ }
+
// Search the KnownFunctionIDs for the identifier.
unsigned i = 0, e = id_num_known_functions;
for (; i != e; ++i) { if (KnownFunctionIDs[i] == FnInfo) break; }
- if (i == e) return;
+ if (i == e) return true;
// Printf checking.
if (i <= id_vprintf) {
@@ -66,6 +73,46 @@
CheckPrintfArguments(Fn, LParenLoc, RParenLoc, HasVAListArg,
FDecl, format_idx, Args, NumArgsInCall);
}
+
+ return true;
+}
+
+/// CheckBuiltinCFStringArgument - Checks that the argument to the builtin
+/// CFString constructor is correct
+bool Sema::CheckBuiltinCFStringArgument(Expr* Arg)
+{
+ while (ParenExpr *PE = dyn_cast<ParenExpr>(Arg))
+ Arg = PE->getSubExpr();
+
+ StringLiteral *Literal = dyn_cast<StringLiteral>(Arg);
+
+ if (!Literal || Literal->isWide()) {
+ Diag(Arg->getLocStart(),
+ diag::err_cfstring_literal_not_string_constant,
+ Arg->getSourceRange());
+ return false;
+ }
+
+ const char *Data = Literal->getStrData();
+ unsigned Length = Literal->getByteLength();
+
+ for (unsigned i = 0; i < Length; ++i) {
+ if (!isascii(Data[i])) {
+ Diag(PP.AdvanceToTokenCharacter(Arg->getLocStart(), i + 1),
+ diag::warn_cfstring_literal_contains_non_ascii_character,
+ Arg->getSourceRange());
+ break;
+ }
+
+ if (!Data[i]) {
+ Diag(PP.AdvanceToTokenCharacter(Arg->getLocStart(), i + 1),
+ diag::warn_cfstring_literal_contains_nul_character,
+ Arg->getSourceRange());
+ break;
+ }
+ }
+
+ return true;
}
/// CheckPrintfArguments - Check calls to printf (and similar functions) for
Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=41136&r1=41135&r2=41136&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Fri Aug 17 00:31:46 2007
@@ -561,7 +561,8 @@
if (ImplicitCastExpr *IcExpr = dyn_cast<ImplicitCastExpr>(Fn))
if (DeclRefExpr *DRExpr = dyn_cast<DeclRefExpr>(IcExpr->getSubExpr()))
if (FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl()))
- CheckFunctionCall(Fn, LParenLoc, RParenLoc, FDecl, Args, NumArgsInCall);
+ if (!CheckFunctionCall(Fn, LParenLoc, RParenLoc, FDecl, Args, NumArgsInCall))
+ return true;
return new CallExpr(Fn, Args, NumArgsInCall, resultType, RParenLoc);
}
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=41136&r1=41135&r2=41136&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Aug 17 00:31:46 2007
@@ -36,8 +36,10 @@
llvm::FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos;
llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos;
llvm::DenseMap<const RecordDecl*, const RecordLayout*> RecordLayoutInfo;
+ RecordDecl *CFConstantStringTypeDecl;
public:
TargetInfo &Target;
+ IdentifierTable &Idents;
Builtin::Context BuiltinInfo;
// Builtin Types.
@@ -50,7 +52,8 @@
QualType FloatTy, DoubleTy, LongDoubleTy;
QualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
- ASTContext(TargetInfo &t, IdentifierTable &idents) : Target(t) {
+ ASTContext(TargetInfo &t, IdentifierTable &idents) :
+ CFConstantStringTypeDecl(0), Target(t), Idents(idents) {
InitBuiltinTypes();
BuiltinInfo.InitializeBuiltins(idents, Target);
}
@@ -116,6 +119,9 @@
/// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
QualType getPointerDiffType() const;
+ // getCFConstantStringType - Return the type used for constant CFStrings.
+ QualType getCFConstantStringType();
+
//===--------------------------------------------------------------------===//
// Type Sizing and Analysis
//===--------------------------------------------------------------------===//
Modified: cfe/trunk/include/clang/AST/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Builtins.def?rev=41136&r1=41135&r2=41136&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Builtins.def (original)
+++ cfe/trunk/include/clang/AST/Builtins.def Fri Aug 17 00:31:46 2007
@@ -29,6 +29,7 @@
// i -> int
// f -> float
// d -> double
+// F -> constant CFString
// . -> "...". This may only occur at the end of the function list.
//
// Types maybe prefixed with the following modifiers:
@@ -36,6 +37,10 @@
// LL -> long long
// S -> signed
// U -> unsigned
+//
+// Types may be postfixed with the following modifiers:
+// * -> pointer
+// C -> const
// The third value provided to the macro specifies information about attributes
// of the function. Currently we have:
@@ -50,5 +55,6 @@
BUILTIN(__builtin_fabsl, "LdLd", "nc")
BUILTIN(__builtin_constant_p, "UsUs", "nc")
BUILTIN(__builtin_classify_type, "i.", "nc")
+BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc")
#undef BUILTIN
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=41136&r1=41135&r2=41136&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Fri Aug 17 00:31:46 2007
@@ -681,6 +681,14 @@
DIAG(warn_printf_format_string_contains_null_char, WARNING,
"format string contains '\\0' within the string body")
+// CFString checking
+DIAG(err_cfstring_literal_not_string_constant, ERROR,
+ "CFString literal is not a string constant")
+DIAG(warn_cfstring_literal_contains_non_ascii_character, WARNING,
+ "CFString literal contains non-ASCII character")
+DIAG(warn_cfstring_literal_contains_nul_character, WARNING,
+ "CFString literal contains NUL character")
+
// Statements.
DIAG(err_continue_not_in_loop, ERROR,
"'continue' statement not in loop statement")
Added: cfe/trunk/test/Sema/cfstring.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/cfstring.c?rev=41136&view=auto
==============================================================================
--- cfe/trunk/test/Sema/cfstring.c (added)
+++ cfe/trunk/test/Sema/cfstring.c Fri Aug 17 00:31:46 2007
@@ -0,0 +1,10 @@
+#define CFSTR __builtin___CFStringMakeConstantString
+
+// RUN: clang %s -parse-ast-check
+void f() {
+ CFSTR("\242"); // expected-warning { CFString literal contains non-ASCII character }
+ CFSTR("\0"); // expected-warning { CFString literal contains NUL character }
+ CFSTR(242); // expected-error { error: CFString literal is not a string constant } \
+ expected-warning { incompatible types }
+ CFSTR("foo", "bar"); // expected-error { error: too many arguments to function }
+}
More information about the cfe-commits
mailing list